@@ -1537,7 +1537,7 @@ <h1>Source code for django.db.models.query_utils</h1><div class="highlight"><pre
15371537< span class ="kn "> from</ span > < span class ="w "> </ span > < span class ="nn "> contextlib</ span > < span class ="w "> </ span > < span class ="kn "> import</ span > < span class ="n "> nullcontext</ span >
15381538
15391539< span class ="kn "> from</ span > < span class ="w "> </ span > < span class ="nn "> django.core.exceptions</ span > < span class ="w "> </ span > < span class ="kn "> import</ span > < span class ="n "> FieldError</ span >
1540- < span class ="kn "> from</ span > < span class ="w "> </ span > < span class ="nn "> django.db</ span > < span class ="w "> </ span > < span class ="kn "> import</ span > < span class ="n "> DEFAULT_DB_ALIAS</ span > < span class ="p "> ,</ span > < span class ="n "> DatabaseError</ span > < span class ="p "> ,</ span > < span class ="n "> connections</ span > < span class ="p "> ,</ span > < span class ="n "> transaction</ span >
1540+ < span class ="kn "> from</ span > < span class ="w "> </ span > < span class ="nn "> django.db</ span > < span class ="w "> </ span > < span class ="kn "> import</ span > < span class ="n "> DEFAULT_DB_ALIAS</ span > < span class ="p "> ,</ span > < span class ="n "> DatabaseError</ span > < span class ="p "> ,</ span > < span class ="n "> connections</ span > < span class ="p "> ,</ span > < span class ="n "> models </ span > < span class =" p " > , </ span > < span class =" n " > transaction</ span >
15411541< span class ="kn "> from</ span > < span class ="w "> </ span > < span class ="nn "> django.db.models.constants</ span > < span class ="w "> </ span > < span class ="kn "> import</ span > < span class ="n "> LOOKUP_SEP</ span >
15421542< span class ="kn "> from</ span > < span class ="w "> </ span > < span class ="nn "> django.utils</ span > < span class ="w "> </ span > < span class ="kn "> import</ span > < span class ="n "> tree</ span >
15431543< span class ="kn "> from</ span > < span class ="w "> </ span > < span class ="nn "> django.utils.functional</ span > < span class ="w "> </ span > < span class ="kn "> import</ span > < span class ="n "> cached_property</ span >
@@ -1572,8 +1572,12 @@ <h1>Source code for django.db.models.query_utils</h1><div class="highlight"><pre
15721572 < span class ="n "> XOR</ span > < span class ="o "> =</ span > < span class ="s2 "> "XOR"</ span >
15731573 < span class ="n "> default</ span > < span class ="o "> =</ span > < span class ="n "> AND</ span >
15741574 < span class ="n "> conditional</ span > < span class ="o "> =</ span > < span class ="kc "> True</ span >
1575+ < span class ="n "> connectors</ span > < span class ="o "> =</ span > < span class ="p "> (</ span > < span class ="kc "> None</ span > < span class ="p "> ,</ span > < span class ="n "> AND</ span > < span class ="p "> ,</ span > < span class ="n "> OR</ span > < span class ="p "> ,</ span > < span class ="n "> XOR</ span > < span class ="p "> )</ span >
15751576
15761577 < span class ="k "> def</ span > < span class ="w "> </ span > < span class ="fm "> __init__</ span > < span class ="p "> (</ span > < span class ="bp "> self</ span > < span class ="p "> ,</ span > < span class ="o "> *</ span > < span class ="n "> args</ span > < span class ="p "> ,</ span > < span class ="n "> _connector</ span > < span class ="o "> =</ span > < span class ="kc "> None</ span > < span class ="p "> ,</ span > < span class ="n "> _negated</ span > < span class ="o "> =</ span > < span class ="kc "> False</ span > < span class ="p "> ,</ span > < span class ="o "> **</ span > < span class ="n "> kwargs</ span > < span class ="p "> ):</ span >
1578+ < span class ="k "> if</ span > < span class ="n "> _connector</ span > < span class ="ow "> not</ span > < span class ="ow "> in</ span > < span class ="bp "> self</ span > < span class ="o "> .</ span > < span class ="n "> connectors</ span > < span class ="p "> :</ span >
1579+ < span class ="n "> connector_reprs</ span > < span class ="o "> =</ span > < span class ="s2 "> ", "</ span > < span class ="o "> .</ span > < span class ="n "> join</ span > < span class ="p "> (</ span > < span class ="sa "> f</ span > < span class ="s2 "> "</ span > < span class ="si "> {</ span > < span class ="n "> conn</ span > < span class ="si "> !r}</ span > < span class ="s2 "> "</ span > < span class ="k "> for</ span > < span class ="n "> conn</ span > < span class ="ow "> in</ span > < span class ="bp "> self</ span > < span class ="o "> .</ span > < span class ="n "> connectors</ span > < span class ="p "> [</ span > < span class ="mi "> 1</ span > < span class ="p "> :])</ span >
1580+ < span class ="k "> raise</ span > < span class ="ne "> ValueError</ span > < span class ="p "> (</ span > < span class ="sa "> f</ span > < span class ="s2 "> "_connector must be one of </ span > < span class ="si "> {</ span > < span class ="n "> connector_reprs</ span > < span class ="si "> }</ span > < span class ="s2 "> , or None."</ span > < span class ="p "> )</ span >
15771581 < span class ="nb "> super</ span > < span class ="p "> ()</ span > < span class ="o "> .</ span > < span class ="fm "> __init__</ span > < span class ="p "> (</ span >
15781582 < span class ="n "> children</ span > < span class ="o "> =</ span > < span class ="p "> [</ span > < span class ="o "> *</ span > < span class ="n "> args</ span > < span class ="p "> ,</ span > < span class ="o "> *</ span > < span class ="nb "> sorted</ span > < span class ="p "> (</ span > < span class ="n "> kwargs</ span > < span class ="o "> .</ span > < span class ="n "> items</ span > < span class ="p "> ())],</ span >
15791583 < span class ="n "> connector</ span > < span class ="o "> =</ span > < span class ="n "> _connector</ span > < span class ="p "> ,</ span >
@@ -1623,6 +1627,45 @@ <h1>Source code for django.db.models.query_utils</h1><div class="highlight"><pre
16231627 < span class ="n "> query</ span > < span class ="o "> .</ span > < span class ="n "> promote_joins</ span > < span class ="p "> (</ span > < span class ="n "> joins</ span > < span class ="p "> )</ span >
16241628 < span class ="k "> return</ span > < span class ="n "> clause</ span >
16251629
1630+ < span class ="k "> def</ span > < span class ="w "> </ span > < span class ="nf "> replace_expressions</ span > < span class ="p "> (</ span > < span class ="bp "> self</ span > < span class ="p "> ,</ span > < span class ="n "> replacements</ span > < span class ="p "> ):</ span >
1631+ < span class ="k "> if</ span > < span class ="ow "> not</ span > < span class ="n "> replacements</ span > < span class ="p "> :</ span >
1632+ < span class ="k "> return</ span > < span class ="bp "> self</ span >
1633+ < span class ="n "> clone</ span > < span class ="o "> =</ span > < span class ="bp "> self</ span > < span class ="o "> .</ span > < span class ="n "> create</ span > < span class ="p "> (</ span > < span class ="n "> connector</ span > < span class ="o "> =</ span > < span class ="bp "> self</ span > < span class ="o "> .</ span > < span class ="n "> connector</ span > < span class ="p "> ,</ span > < span class ="n "> negated</ span > < span class ="o "> =</ span > < span class ="bp "> self</ span > < span class ="o "> .</ span > < span class ="n "> negated</ span > < span class ="p "> )</ span >
1634+ < span class ="k "> for</ span > < span class ="n "> child</ span > < span class ="ow "> in</ span > < span class ="bp "> self</ span > < span class ="o "> .</ span > < span class ="n "> children</ span > < span class ="p "> :</ span >
1635+ < span class ="n "> child_replacement</ span > < span class ="o "> =</ span > < span class ="n "> child</ span >
1636+ < span class ="k "> if</ span > < span class ="nb "> isinstance</ span > < span class ="p "> (</ span > < span class ="n "> child</ span > < span class ="p "> ,</ span > < span class ="nb "> tuple</ span > < span class ="p "> ):</ span >
1637+ < span class ="n "> lhs</ span > < span class ="p "> ,</ span > < span class ="n "> rhs</ span > < span class ="o "> =</ span > < span class ="n "> child</ span >
1638+ < span class ="k "> if</ span > < span class ="n "> LOOKUP_SEP</ span > < span class ="ow "> in</ span > < span class ="n "> lhs</ span > < span class ="p "> :</ span >
1639+ < span class ="n "> path</ span > < span class ="p "> ,</ span > < span class ="n "> lookup</ span > < span class ="o "> =</ span > < span class ="n "> lhs</ span > < span class ="o "> .</ span > < span class ="n "> rsplit</ span > < span class ="p "> (</ span > < span class ="n "> LOOKUP_SEP</ span > < span class ="p "> ,</ span > < span class ="mi "> 1</ span > < span class ="p "> )</ span >
1640+ < span class ="k "> else</ span > < span class ="p "> :</ span >
1641+ < span class ="n "> path</ span > < span class ="o "> =</ span > < span class ="n "> lhs</ span >
1642+ < span class ="n "> lookup</ span > < span class ="o "> =</ span > < span class ="kc "> None</ span >
1643+ < span class ="n "> field</ span > < span class ="o "> =</ span > < span class ="n "> models</ span > < span class ="o "> .</ span > < span class ="n "> F</ span > < span class ="p "> (</ span > < span class ="n "> path</ span > < span class ="p "> )</ span >
1644+ < span class ="k "> if</ span > < span class ="p "> (</ span >
1645+ < span class ="n "> field_replacement</ span > < span class ="o "> :=</ span > < span class ="n "> field</ span > < span class ="o "> .</ span > < span class ="n "> replace_expressions</ span > < span class ="p "> (</ span > < span class ="n "> replacements</ span > < span class ="p "> )</ span >
1646+ < span class ="p "> )</ span > < span class ="ow "> is</ span > < span class ="ow "> not</ span > < span class ="n "> field</ span > < span class ="p "> :</ span >
1647+ < span class ="c1 "> # Handle the implicit __exact case by falling back to an</ span >
1648+ < span class ="c1 "> # extra transform when get_lookup returns no match for the</ span >
1649+ < span class ="c1 "> # last component of the path.</ span >
1650+ < span class ="k "> if</ span > < span class ="n "> lookup</ span > < span class ="ow "> is</ span > < span class ="kc "> None</ span > < span class ="p "> :</ span >
1651+ < span class ="n "> lookup</ span > < span class ="o "> =</ span > < span class ="s2 "> "exact"</ span >
1652+ < span class ="k "> if</ span > < span class ="p "> (</ span > < span class ="n "> lookup_class</ span > < span class ="o "> :=</ span > < span class ="n "> field_replacement</ span > < span class ="o "> .</ span > < span class ="n "> get_lookup</ span > < span class ="p "> (</ span > < span class ="n "> lookup</ span > < span class ="p "> ))</ span > < span class ="ow "> is</ span > < span class ="kc "> None</ span > < span class ="p "> :</ span >
1653+ < span class ="k "> if</ span > < span class ="p "> (</ span >
1654+ < span class ="n "> transform_class</ span > < span class ="o "> :=</ span > < span class ="n "> field_replacement</ span > < span class ="o "> .</ span > < span class ="n "> get_transform</ span > < span class ="p "> (</ span > < span class ="n "> lookup</ span > < span class ="p "> )</ span >
1655+ < span class ="p "> )</ span > < span class ="ow "> is</ span > < span class ="ow "> not</ span > < span class ="kc "> None</ span > < span class ="p "> :</ span >
1656+ < span class ="n "> field_replacement</ span > < span class ="o "> =</ span > < span class ="n "> transform_class</ span > < span class ="p "> (</ span > < span class ="n "> field_replacement</ span > < span class ="p "> )</ span >
1657+ < span class ="n "> lookup</ span > < span class ="o "> =</ span > < span class ="s2 "> "exact"</ span >
1658+ < span class ="n "> lookup_class</ span > < span class ="o "> =</ span > < span class ="n "> field_replacement</ span > < span class ="o "> .</ span > < span class ="n "> get_lookup</ span > < span class ="p "> (</ span > < span class ="n "> lookup</ span > < span class ="p "> )</ span >
1659+ < span class ="k "> if</ span > < span class ="n "> rhs</ span > < span class ="ow "> is</ span > < span class ="kc "> None</ span > < span class ="ow "> and</ span > < span class ="n "> lookup</ span > < span class ="o "> ==</ span > < span class ="s2 "> "exact"</ span > < span class ="p "> :</ span >
1660+ < span class ="n "> lookup_class</ span > < span class ="o "> =</ span > < span class ="n "> field_replacement</ span > < span class ="o "> .</ span > < span class ="n "> get_lookup</ span > < span class ="p "> (</ span > < span class ="s2 "> "isnull"</ span > < span class ="p "> )</ span >
1661+ < span class ="n "> rhs</ span > < span class ="o "> =</ span > < span class ="kc "> True</ span >
1662+ < span class ="k "> if</ span > < span class ="n "> lookup_class</ span > < span class ="ow "> is</ span > < span class ="ow "> not</ span > < span class ="kc "> None</ span > < span class ="p "> :</ span >
1663+ < span class ="n "> child_replacement</ span > < span class ="o "> =</ span > < span class ="n "> lookup_class</ span > < span class ="p "> (</ span > < span class ="n "> field_replacement</ span > < span class ="p "> ,</ span > < span class ="n "> rhs</ span > < span class ="p "> )</ span >
1664+ < span class ="k "> else</ span > < span class ="p "> :</ span >
1665+ < span class ="n "> child_replacement</ span > < span class ="o "> =</ span > < span class ="n "> child</ span > < span class ="o "> .</ span > < span class ="n "> replace_expressions</ span > < span class ="p "> (</ span > < span class ="n "> replacements</ span > < span class ="p "> )</ span >
1666+ < span class ="n "> clone</ span > < span class ="o "> .</ span > < span class ="n "> children</ span > < span class ="o "> .</ span > < span class ="n "> append</ span > < span class ="p "> (</ span > < span class ="n "> child_replacement</ span > < span class ="p "> )</ span >
1667+ < span class ="k "> return</ span > < span class ="n "> clone</ span >
1668+
16261669 < span class ="k "> def</ span > < span class ="w "> </ span > < span class ="nf "> flatten</ span > < span class ="p "> (</ span > < span class ="bp "> self</ span > < span class ="p "> ):</ span >
16271670< span class ="w "> </ span > < span class ="sd "> """</ span >
16281671< span class ="sd "> Recursively yield this Q object and all subexpressions, in depth-first</ span >
@@ -2047,7 +2090,7 @@ <h1>Source code for django.db.models.query_utils</h1><div class="highlight"><pre
20472090
20482091 </ aside >
20492092 </ div >
2050- </ div > < script src ="../../../../_static/documentation_options.js?v=3e613aec "> </ script >
2093+ </ div > < script src ="../../../../_static/documentation_options.js?v=1d6abbee "> </ script >
20512094 < script src ="../../../../_static/doctools.js?v=9bcbadda "> </ script >
20522095 < script src ="../../../../_static/sphinx_highlight.js?v=dc90522c "> </ script >
20532096 < script src ="../../../../_static/scripts/furo.js?v=46bd48cc "> </ script >
0 commit comments