
    ,iL                     X   d Z ddlZddlZddlZddlmZ ddlmZ ddlm	Z	 ddl
mZmZmZmZmZ ddlmZ ddlmZ dd	lmZ dd
lmZ  ej0                  d      Z edd      Zd Z G d dej8                        Z G d d      Z G d d      Z G d d      Z d Z!d Z"d Z# G d d      Z$y)z
Various data structures used in query construction.

Factored out from django.db.models.query to avoid making the main module very
large and/or so that they can be used by other modules without getting into
circular import difficulties.
    N)
namedtuple)nullcontext)
FieldError)DEFAULT_DB_ALIASDatabaseErrorconnectionsmodelstransaction)
LOOKUP_SEP)tree)cached_property)make_hashabledjango.db.modelsPathInfozGfrom_opts to_opts target_fields join_field m2m direct filtered_relationc              #   h   K   |  | j                         D ]  }t        |      E d {     y 7 wN)__subclasses__
subclassesclssubclasss     P/var/www/mymood/env/lib/python3.12/site-packages/django/db/models/query_utils.pyr   r   !   s/     
I&&(h''' )'s   &202c                        e Zd ZdZdZdZdZeZdZdeeefZ	ddd fd	
Z
d
 Zd Zd Zd Zd Z	 ddZd Zd ZefdZd Zed        Zd Zd Zed        Z xZS )Qze
    Encapsulate filters as objects that can then be combined logically (using
    `&` and `|`).
    ANDORXORTNF)
_connector_negatedc                    || j                   vr4dj                  d | j                   dd  D              }t        d| d      t        |   g |t        |j                               ||       y )Nz, c              3   "   K   | ]  }| 	 y wr    ).0conns     r   	<genexpr>zQ.__init__.<locals>.<genexpr>7   s     'T@S4(@Ss      z_connector must be one of z
, or None.)children	connectornegated)
connectorsjoin
ValueErrorsuper__init__sorteditems)selfr   r   argskwargsconnector_reprs	__class__s         r   r.   z
Q.__init__5   sv    T__,"ii'TPQPR@S'TTO9/9J*UVV5t5fV\\^45  	 	
    c                    t        |dd      du rt        |      | s|j                         S |s t        |t              r| j                         S | j                  |      }|j                  | |       |j                  ||       |S )NconditionalF)r(   )getattr	TypeErrorcopy
isinstancer   createadd)r1   otherr$   objs       r   _combinez
Q._combine?   sv    5-/58E""::<E1-99;kkDk)dt
r6   c                 :    | j                  || j                        S r   )rA   r   r1   r?   s     r   __or__zQ.__or__L   s    }}UDGG,,r6   c                 :    | j                  || j                        S r   )rA   r   rC   s     r   __and__z	Q.__and__O       }}UDHH--r6   c                 :    | j                  || j                        S r   )rA   r   rC   s     r   __xor__z	Q.__xor__R   rG   r6   c                 F    | j                         }|j                          |S r   )r;   negate)r1   r@   s     r   
__invert__zQ.__invert__U   s    iik


r6   c                 \    |j                  | ||dd|      \  }}|j                  |       |S )NF)allow_joins
split_subqcheck_filterable	summarize)_add_qpromote_joins)r1   queryrN   reuserQ   for_saveclausejoinss           r   resolve_expressionzQ.resolve_expressionZ   sB    
 #" % 
 	E"r6   c                    |s| S | j                  | j                  | j                        }| j                  D ]  }|}t	        |t
              r|\  }}t        |v r|j                  t        d      \  }}n|}d }t        j                  |      }	|	j                  |      x}
|	ur}|d}|
j                  |      x}/|
j                  |      x}	  ||
      }
d}|
j                  |      }||dk(  r|
j                  d      }d}| ||
|      }n|j                  |      }|j                  j                  |        |S )N)r(   r)   r&   exactisnullT)r=   r(   r)   r'   r<   tupler   rsplitr	   Freplace_expressions
get_lookupget_transformappend)r1   replacementsclonechildchild_replacementlhsrhspathlookupfieldfield_replacementlookup_classtransform_classs                r   r`   zQ.replace_expressionsj   s]   KdnndllK]]E %%' S$#&::j!#<LD&D!F).)B)B<)PP% ~!((9(D(DV(LLU/@/N/Nv/VVO!%& 1@@Q0R-%,F+<+G+G+OL{v'8'8'C'CH'M"#/,89JC,P)$)$=$=l$K!NN!!"34A #B r6   c              #      K   |  | j                   D ]@  }t        |t              r|d   }t        |d      r|j	                         E d{    =| B y7 w)zg
        Recursively yield this Q object and all subexpressions, in depth-first
        order.
        r&   flattenN)r'   r<   r]   hasattrrq   )r1   rf   s     r   rq   z	Q.flatten   sQ     
 
]]E%'aui( ==?** #
 +s   AA
AAc           
         ddl m}m} ddlm} ddlm} ddlm}  |d      }|j                         D ]-  \  }	}
t        |
d      s ||
      }
|j                  |
|	d	       / |j                   |d
      d       t        |   }|j                  j                  r)|j                  t!         || d |                          n|j                  |        |j#                  |      }|j$                  rt'        j(                  |      n	t+               }	 |5  |j-                  |      ducddd       S # 1 sw Y   yxY w# t.        $ r!}t0        j3                  d| |       Y d}~yd}~ww xY w)z|
        Do a database query to check if the expressions of the Q instance
        matches against the expressions.
        r   )BooleanFieldValue)Coalesce)Query)SINGLENrY   F)selectr&   _checkT)output_field)usingz.Got a database error calling check() on %r: %s)django.db.modelsrt   ru   django.db.models.functionsrv   django.db.models.sqlrw   django.db.models.sql.constantsrx   r0   rr   add_annotationr   featuressupports_comparing_boolean_expradd_qr   get_compilerin_atomic_blockr
   atomicr   execute_sqlr   loggerwarning)r1   againstr|   rt   ru   rv   rw   rx   rT   namevalue
connectioncompilercontext_manageres                  r   checkzQ.check   s.    	97.9d"==?KD%5"67e  U ; + 	U1Xx0 '
>>KK(4LNKLMKK%%E%2 )) U+ 	
	 ++F34? ! 	NNKTSTU	s6   D> D2(	D> 2D;7D> ;D> >	E(E##E(c                 P   | j                   j                  d| j                   j                  }|j                  d      r|j	                  dd      }t        | j                        }i }| j                  | j                  k7  r| j                  |d<   | j                  rd|d<   |||fS )N.zdjango.db.models.query_utilsr   r   Tr   )
r5   
__module____name__
startswithreplacer]   r'   r(   defaultr)   )r1   rj   r2   r3   s       r   deconstructzQ.deconstruct   s    ..33T^^5L5LM??9:<< >@RSDT]]#>>T\\)#'>>F< <<!%F:T6!!r6   c                     | j                         \  }}}|g|j                         }|D ]G  }t        |t              r$|\  }}t	        |      }|j                  ||f       7|j                  |       I t        |      S r   )r   r0   r<   r]   r   rc   )r1   rj   r2   r3   identityrf   argr   s           r   r   z
Q.identity   sy    !--/dF*6<<>*E%'"
U%e,e-&  Xr6   c                 `    t        |t              st        S |j                  | j                  k(  S r   )r<   r   NotImplementedr   rC   s     r   __eq__zQ.__eq__   s%    %#!!~~..r6   c                 ,    t        | j                        S r   )hashr   )r1   s    r   __hash__z
Q.__hash__   s    DMM""r6   c                     ddl m} |j                  |       D ch c]  }|j                  t        d      d    c}S c c}w )z
        Retrieve all base fields referenced directly or through F expressions
        excluding any fields referenced through joins.
        r   )rT   r&   )r   rT   get_children_from_qsplitr   )r1   rT   rf   s      r   referenced_base_fieldszQ.referenced_base_fields   sG     	/ 8=7P7PQU7V
7VeEKK
A&q)7V
 	
 
s    =)NTNFF)r   r   __qualname____doc__r   r   r   r   r8   r*   r.   rA   rD   rF   rI   rL   rY   r`   rq   r   r   r   r   r   r   r   r   __classcell__)r5   s   @r   r   r   '   s     C	B
CGKR%J)- 
-.. SX %N $4 "H
" 
 
/
# 

 

r6   r   c                   $    e Zd ZdZd ZddZd Zy)DeferredAttributez
    A wrapper for a deferred-loading field. When the value is read from this
    object the first time, the query is executed.
    c                     || _         y r   )rl   )r1   rl   s     r   r.   zDeferredAttribute.__init__   s	    
r6   Nc                 "   || S |j                   }| j                  j                  }||vra| j                  |      }|I|j	                         s!| j                  j
                  rt        d      |j                  |g       ||   S |||<   ||   S )zx
        Retrieve and caches the value from the datastore on the first lookup.
        Return the cached value.
        z4Cannot read a generated field from an unsaved model.)fields)__dict__rl   attname_check_parent_chain
_is_pk_set	generatedAttributeErrorrefresh_from_db)r1   instancer   data
field_namevals         r   __get__zDeferredAttribute.__get__   s    
 K  ZZ''
T! **84C{**,1E1E(N  (((= J $'Z Jr6   c                     |j                   }|j                  | j                  j                        }| j                  j                  r%| j                  |k7  rt        ||j                        S y)z
        Check if the field value can be fetched from a parent field already
        loaded in the instance. This can be done if the to-be fetched
        field is a primary key field.
        N)_metaget_ancestor_linkrl   modelprimary_keyr9   r   )r1   r   opts
link_fields       r   r   z%DeferredAttribute._check_parent_chain  sU     ~~++DJJ,<,<=
::!!djjJ&>8Z%7%788r6   r   )r   r   r   r   r.   r   r   r"   r6   r   r   r      s    
 .
r6   r   c                       e Zd ZdZd Zd Zy)class_or_instance_methodz
    Hook used in RegisterLookupMixin to return partial functions depending on
    the caller type (instance or class of models.Field).
    c                      || _         || _        y r   )class_methodinstance_method)r1   r   r   s      r   r.   z!class_or_instance_method.__init__&  s    (.r6   c                     | t        j                  | j                  |      S t        j                  | j                  |      S r   )	functoolspartialr   r   )r1   r   owners      r   r   z class_or_instance_method.__get__*  s:    $$T%6%6>>  !5!5x@@r6   N)r   r   r   r   r.   r   r"   r6   r   r   r      s    
/Ar6   r   c                       e Zd Zd Zej
                  d        Zd Z eee      Z	 e
e      Zd Zd Zed        Ze
d        Zdd	Zdd
Z eee      Z e
e      ZddZddZ eee      Z e
e      Zy)RegisterLookupMixinc                 B    | j                         j                  |d       S r   )get_lookupsget)r1   lookup_names     r   _get_lookupzRegisterLookupMixin._get_lookup1  s    !%%k488r6   c                     t        j                  |       D cg c]  }|j                  j                  di         }}| j	                  |      S c c}w Nclass_lookups)inspectgetmror   r   merge_dicts)r   parentr   s      r   get_class_lookupsz%RegisterLookupMixin.get_class_lookups4  sT     DK>>RUCV
CVFOO4CV 	 
 }--
s   #Ac                 P    | j                         }t        | dd       x}ri ||S |S Ninstance_lookups)r   r9   )r1   r   r   s      r   get_instance_lookupsz(RegisterLookupMixin.get_instance_lookups;  s=    ..0&t-?FFF8m8'788r6   c                     ddl m} | j                  |      }|'t        | d      r| j                  j                  |      S |t        ||      sy |S )Nr   )Lookupr{   )django.db.models.lookupsr   r   rr   r{   ra   
issubclass)r1   r   r   founds       r   ra   zRegisterLookupMixin.get_lookupD  sQ    3  -=WT>:$$//<<Zv%>r6   c                     ddl m} | j                  |      }|'t        | d      r| j                  j                  |      S |t        ||      sy |S )Nr   )	Transformr{   )r   r   r   rr   r{   rb   r   )r1   r   r   r   s       r   rb   z!RegisterLookupMixin.get_transformN  sQ    6  -=WT>:$$22;??Zy%Ar6   c                 L    i }t        |       D ]  }|j                  |        |S )z
        Merge dicts in reverse to preference the order of the original list. e.g.,
        merge_dicts([a, b]) will preference the keys in 'a' over those in 'b'.
        )reversedupdate)dictsmergedds      r   r   zRegisterLookupMixin.merge_dictsX  s(     %AMM! !r6   c                 X    t        |       D ]  }|j                  j                           y r   )r   r   cache_clearr   s     r   _clear_cached_class_lookupsz/RegisterLookupMixin._clear_cached_class_lookupsc  s"    "3H&&224 (r6   Nc                     ||j                   }d| j                  vri | _        || j                  |<   | j                          |S r   )r   r   r   r   r   rk   r   s      r   register_class_lookupz)RegisterLookupMixin.register_class_lookuph  sH     ,,K#,,. "C)/+&'')r6   c                 j    ||j                   }d| j                  vri | _        || j                  |<   |S r   )r   r   r   r1   rk   r   s      r   register_instance_lookupz,RegisterLookupMixin.register_instance_lookupq  s<     ,,KT]]2$&D!-3k*r6   c                 Z    ||j                   }| j                  |= | j                          y)zn
        Remove given lookup from cls lookups. For use in tests only as it's
        not thread-safe.
        N)r   r   r   r   s      r   _unregister_class_lookupz,RegisterLookupMixin._unregister_class_lookup~  s/    
  ,,Kk*'')r6   c                 :    ||j                   }| j                  |= y)zs
        Remove given lookup from instance lookups. For use in tests only as
        it's not thread-safe.
        N)r   r   r   s      r   _unregister_instance_lookupz/RegisterLookupMixin._unregister_instance_lookup  s#    
  ,,K!!+.r6   r   )r   r   r   r   r   cacher   r   r   r   classmethodra   rb   staticmethodr   r   r   r   register_lookupr   r   _unregister_lookupr"   r6   r   r   r   0  s    9 __. . ++<>RSK#$56   5 5 /7O ((=>*/ 2 "=  ++CDr6   r   c                 
   | j                   syt        | j                   dd      ry|s| j                   S | j                  |vry|r>| |vr:t	        d| j
                  j                  j                   d| j                   d      y)a  
    Return whether `field` should be used to descend deeper for
    `select_related()` purposes.

    Arguments:
     * `field` - the field to be checked. Can be either a `Field` or
       `ForeignObjectRel` instance.
     * `restricted` - a boolean field, indicating if the field list has been
       manually restricted using a select_related() clause.
     * `requested` - the select_related() dictionary.
     * `select_mask` - the dictionary of selected fields.
    Fparent_linkzField r   zM cannot be both deferred and traversed using select_related at the same time.T)remote_fieldr9   nullr   r   r   r   object_name)rl   
restricted	requestedselect_masks       r   select_related_descendr    s      u!!=%8 ::~ zz" uK/U[[&&2231UZZL AL L
 	
 r6   c                     t        dt        |       dz         D ]4  }t        j                  | d|       }|j	                  |      s-|| |d fc S  y)z
    Check if the lookup_parts contains references to the given annotations set.
    Because the LOOKUP_SEP is contained in the default annotation names, check
    each prefix of the lookup_parts for a match.
    r&   r   N)Nr"   )rangelenr   r+   r   )lookup_partsannotationsnlevel_n_lookups       r   refs_expressionr    sW     1c,'!+,#a):;??>*!<#333 - r6   c                 x      fd} ||      xs+ t        |dd      xr  ||j                  j                        S )z
    Check that self.model is compatible with target_opts. Compatibility
    is OK if:
      1) model and opts match (where proxy inheritance is removed)
      2) model is parent of opts' model or the other way around
    c                     j                   j                  | j                  k(  xs2 | j                  j                   j                  v xs | j                  v S r   )r   concrete_modelall_parents)r   r   s    r   r   z-check_rel_lookup_compatibility.<locals>.check  sP    KK&&$*=*== )""ekk&=&==)(((	
r6   r   F)r9   r   r   )r   target_optsrl   r   s   `   r   check_rel_lookup_compatibilityr    s<    
   }e,Iu{{7H7H1Ir6   c                   D    e Zd ZdZ e       ddZd Zd Zd Zd Z	d Z
y	)
FilteredRelationz7Specify custom filtering in the ON clause of SQL joins.	conditionc                    |st        d      || _        d | _        t        |t              st        d      || _        d | _        y )Nzrelation_name cannot be empty.z*condition argument must be a Q() instance.)r,   relation_namealiasr<   r   r  resolved_condition)r1   r  r  s      r   r.   zFilteredRelation.__init__  sG    =>>*
)Q'IJJ #"&r6   c                     t        || j                        st        S | j                  |j                  k(  xr4 | j                  |j                  k(  xr | j
                  |j
                  k(  S r   )r<   r5   r   r  r  r  rC   s     r   r   zFilteredRelation.__eq__  sY    %0!!%"5"55 2

ekk)2%//1	
r6   c                     t        | j                  | j                        }| j                  |_        | j                  x}|j                         |_        |S )Nr  )r  r  r  r  r  re   )r1   re   r  s      r   re   zFilteredRelation.clone   sK     !3!3t~~Njj"&"9"99F'9'?'?'AE$r6   c                 n    | j                         }|j                  x}r|j                  |      |_        |S r   )re   r  relabeled_clone)r1   
change_mapre   r  s       r   r   z FilteredRelation.relabeled_clone  s7    

!&!9!999'9'I'I*'UE$r6   c                 v    | j                         }|j                  | j                  |ddd      d   |_        |S )NTF)	can_reuserN   rO   update_join_typesr   )re   build_filterr  r  )r1   rT   rU   r2   r3   re   s         r   rY   z#FilteredRelation.resolve_expression  sI    

#(#5#5NN# $6 $
 $  r6   c                 8    |j                  | j                        S r   )compiler  )r1   r   r   s      r   as_sqlzFilteredRelation.as_sql  s     7 788r6   N)r   r   r   r   r   r.   r   re   r   rY   r(  r"   r6   r   r  r    s(    A343 '
	9r6   r  )%r   r   r   loggingcollectionsr   
contextlibr   django.core.exceptionsr   	django.dbr   r   r   r	   r
   django.db.models.constantsr   django.utilsr   django.utils.functionalr   django.utils.hashabler   	getLoggerr   r   r   Noder   r   r   r   r  r  r  r  r"   r6   r   <module>r4     s       " " - W W 1  3 /			-	.
 M(I
		 I
X* *ZA A dE dEN#L
:29 29r6   