o
    ×ŸŽiŒ;  ã                   @   sä   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	m
Z
mZ ddlmZ ddlmZ e d¡Zed	d
ƒZdd„ ZG dd„ dejƒZG dd„ dƒZG dd„ dƒZG dd„ dƒZddd„Zdd„ Zdd„ ZG dd„ dƒZdS )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)Ú
FieldError)ÚDEFAULT_DB_ALIASÚDatabaseErrorÚconnections)Ú
LOOKUP_SEP)Útreeúdjango.db.modelsÚPathInfozGfrom_opts to_opts target_fields join_field m2m direct filtered_relationc                 c   s(   � | V  |   ¡ D ]	}t|ƒE d H  qd S ©N)Ú__subclasses__Ú
subclasses©ÚclsÚsubclass© r   úfC:\Users\psant\Downloads\Anu Raj Backend\school\venv\Lib\site-packages\django/db/models/query_utils.pyr      s
   €ÿr   c                       sŒ   e Zd ZdZdZdZdZeZdZdddœ‡ fd	d
„
Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Z	ddd„Zdd„ Zefdd„Zdd„ Z‡  ZS )ÚQze
    Encapsulate filters as objects that can then be combined logically (using
    `&` and `|`).
    ÚANDÚORÚXORTNF)Ú
_connectorÚ_negatedc                   s&   t ƒ jg |¢t| ¡ ƒ¢||d� d S )N)ÚchildrenÚ	connectorÚnegated)ÚsuperÚ__init__ÚsortedÚitems)Úselfr   r   ÚargsÚkwargs©Ú	__class__r   r   r   0   s
   
ýz
Q.__init__c                 C   sb   t |ddƒdu rt|ƒ‚| s| ¡ S |st|tƒr|  ¡ S | j|d�}| | |¡ | ||¡ |S )NÚconditionalF)r   )ÚgetattrÚ	TypeErrorÚcopyÚ
isinstancer   ÚcreateÚadd)r    ÚotherÚconnÚobjr   r   r   Ú_combine7   s   z
Q._combinec                 C   ó   |   || j¡S r   )r/   r   ©r    r,   r   r   r   Ú__or__D   ó   zQ.__or__c                 C   r0   r   )r/   r   r1   r   r   r   Ú__and__G   r3   z	Q.__and__c                 C   r0   r   )r/   r   r1   r   r   r   Ú__xor__J   r3   z	Q.__xor__c                 C   s   |   ¡ }| ¡  |S r   )r(   Únegate)r    r.   r   r   r   Ú
__invert__M   s   zQ.__invert__c                 C   s(   |j | ||dd|d�\}}| |¡ |S )NF)Úallow_joinsZ
split_subqZcheck_filterableÚ	summarize)Z_add_qZpromote_joins)r    Úqueryr8   Úreuser9   Zfor_saveZclauseZjoinsr   r   r   Úresolve_expressionR   s   
ú
zQ.resolve_expressionc                 c   sJ   � | V  | j D ]}t|tƒr|d }t|dƒr| ¡ E dH  q|V  qdS )zg
        Recursively yield this Q object and all subexpressions, in depth-first
        order.
        é   ÚflattenN)r   r)   ÚtupleÚhasattrr>   )r    Úchildr   r   r   r>   b   s   €


ùz	Q.flattenc              
   C   s  ddl m}m} ddlm} ddlm} ddlm} |dƒ}| 	¡ D ]\}	}
t
|
dƒs/||
ƒ}
|j|
|	dd	� q"| |d
ƒd¡ t| jjrT| t|| d|ƒ d�ƒ¡ n| | ¡ |j|d�}z| |¡duW S  ty� } zt d| |¡ W Y d}~dS d}~ww )z|
        Do a database query to check if the expressions of the Q instance
        matches against the expressions.
        r   )ÚBooleanFieldÚValue)ÚCoalesce)ÚQuery)ÚSINGLENr<   F)Úselectr=   Ú_checkT)Úoutput_field)Úusingz.Got a database error calling check() on %r: %s)Zdjango.db.modelsrB   rC   Zdjango.db.models.functionsrD   Zdjango.db.models.sqlrE   Zdjango.db.models.sql.constantsrF   r   r@   Zadd_annotationr   ÚfeaturesZsupports_comparing_boolean_exprZadd_qr   Zget_compilerZexecute_sqlr   ÚloggerÚwarning)r    ZagainstrJ   rB   rC   rD   rE   rF   r:   ÚnameÚvalueÚcompilerÚer   r   r   Úcheckq   s*   

€þzQ.checkc                 C   sf   d| j j| j jf }| d¡r| dd¡}t| jƒ}i }| j| jkr'| j|d< | j	r.d|d< |||fS )Nz%s.%szdjango.db.models.query_utilsr	   r   Tr   )
r$   Ú
__module__Ú__name__Ú
startswithÚreplacer?   r   r   Údefaultr   )r    Úpathr!   r"   r   r   r   ÚdeconstructŽ   s   



zQ.deconstruct)NTNFF)rT   rS   Ú__qualname__Ú__doc__r   r   r   rW   r%   r   r/   r2   r4   r5   r7   r<   r>   r   rR   rY   Ú__classcell__r   r   r#   r   r   #   s$    
ÿr   c                   @   s*   e Zd ZdZdd„ Zd	dd„Zdd„ ZdS )
ÚDeferredAttributez„
    A wrapper for a deferred-loading field. When the value is read from this
    object the first time, the query is executed.
    c                 C   s
   || _ d S r   )Úfield)r    r^   r   r   r   r   ¡   s   
zDeferredAttribute.__init__Nc                 C   sZ   |du r| S |j }| jj}||vr)|  |¡}|du r%|j|gd� || S |||< || S )zx
        Retrieve and caches the value from the datastore on the first lookup.
        Return the cached value.
        N)Úfields)Ú__dict__r^   ÚattnameÚ_check_parent_chainZrefresh_from_db)r    Úinstancer   ÚdataÚ
field_nameÚvalr   r   r   Ú__get__¤   s   
ÿzDeferredAttribute.__get__c                 C   s6   |j }| | jj¡}| jjr| j|krt||jƒS dS )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)Ú_metaZget_ancestor_linkr^   ÚmodelÚprimary_keyr&   ra   )r    rc   ÚoptsZ
link_fieldr   r   r   rb   ·   s
   z%DeferredAttribute._check_parent_chainr   )rT   rS   rZ   r[   r   rg   rb   r   r   r   r   r]   ›   s
    
r]   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )Úclass_or_instance_methodzŒ
    Hook used in RegisterLookupMixin to return partial functions depending on
    the caller type (instance or class of models.Field).
    c                 C   s   || _ || _d S r   )Úclass_methodÚinstance_method)r    rm   rn   r   r   r   r   Ê   s   
z!class_or_instance_method.__init__c                 C   s$   |d u rt  | j|¡S t  | j|¡S r   )Ú	functoolsÚpartialrm   rn   )r    rc   Úownerr   r   r   rg   Î   s   z class_or_instance_method.__get__N)rT   rS   rZ   r[   r   rg   r   r   r   r   rl   Ä   s    rl   c                   @   s¶   e Zd Zdd„ Zejdd�dd„ ƒZdd„ ZeeeƒZ	e
eƒZd	d
„ Zdd„ Zedd„ ƒZe
dd„ ƒZddd„Zddd„ZeeeƒZe
eƒZddd„Zddd„ZeeeƒZe
eƒZdS )ÚRegisterLookupMixinc                 C   s   |   ¡  |d ¡S r   )Úget_lookupsÚget)r    Úlookup_namer   r   r   Ú_get_lookupÕ   s   zRegisterLookupMixin._get_lookupN)Úmaxsizec                 C   s   dd„ t  | ¡D ƒ}|  |¡S )Nc                 S   s   g | ]	}|j  d i ¡‘qS )Úclass_lookups)r`   rt   )Ú.0Úparentr   r   r   Ú
<listcomp>Ú   s    ÿz9RegisterLookupMixin.get_class_lookups.<locals>.<listcomp>)ÚinspectÚgetmroÚmerge_dicts)r   rx   r   r   r   Úget_class_lookupsØ   s   ÿ
z%RegisterLookupMixin.get_class_lookupsc                 C   s(   |   ¡ }t| dd ƒ }ri |¥|¥S |S ©NÚinstance_lookups)r   r&   )r    rx   r�   r   r   r   Úget_instance_lookupsß   s   z(RegisterLookupMixin.get_instance_lookupsc                 C   óN   ddl m} |  |¡}|d u rt| dƒr| j |¡S |d ur%t||ƒs%d S |S )Nr   )ÚLookuprI   )Údjango.db.models.lookupsr„   rv   r@   rI   Ú
get_lookupÚ
issubclass)r    ru   r„   Úfoundr   r   r   r†   è   ó   
zRegisterLookupMixin.get_lookupc                 C   rƒ   )Nr   )Ú	TransformrI   )r…   rŠ   rv   r@   rI   Úget_transformr‡   )r    ru   rŠ   rˆ   r   r   r   r‹   ò   r‰   z!RegisterLookupMixin.get_transformc                 C   s    i }t | ƒD ]}| |¡ q|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'.
        N)ÚreversedÚupdate)ZdictsÚmergedÚdr   r   r   r~   ü   s   zRegisterLookupMixin.merge_dictsc                 C   s   t | ƒD ]}|j ¡  qd S r   )r   r   Úcache_clearr   r   r   r   Ú_clear_cached_class_lookups  s   ÿz/RegisterLookupMixin._clear_cached_class_lookupsc                 C   s4   |d u r|j }d| jvri | _|| j|< |  ¡  |S )Nrx   )ru   r`   rx   r‘   ©r   Úlookupru   r   r   r   Úregister_class_lookup  s   

z)RegisterLookupMixin.register_class_lookupc                 C   s,   |d u r|j }d| jvri | _|| j|< |S r€   )ru   r`   r�   ©r    r“   ru   r   r   r   Úregister_instance_lookup  s   

z,RegisterLookupMixin.register_instance_lookupc                 C   s"   |du r|j }| j|= |  ¡  dS )zn
        Remove given lookup from cls lookups. For use in tests only as it's
        not thread-safe.
        N)ru   rx   r‘   r’   r   r   r   Ú_unregister_class_lookup"  s   z,RegisterLookupMixin._unregister_class_lookupc                 C   s   |du r|j }| j|= dS )zs
        Remove given lookup from instance lookups. For use in tests only as
        it's not thread-safe.
        N)ru   r�   r•   r   r   r   Ú_unregister_instance_lookup,  s   z/RegisterLookupMixin._unregister_instance_lookupr   )rT   rS   rZ   rv   ro   Ú	lru_cacher   r‚   rl   rs   Úclassmethodr†   r‹   Ústaticmethodr~   r‘   r”   r–   Zregister_lookupr—   r˜   Z_unregister_lookupr   r   r   r   rr   Ô   s2    









	ÿ


	ÿrr   Fc                 C   sŽ   | j sdS | j jr|sdS |r"|r|  ¡ |vrdS |s"| j|vr"dS |s)| jr)dS |rE|rE| j|v rE| |vrEtd| jjj› d| j› d�ƒ‚dS )af  
    Return True if this field should be used to descend deeper for
    select_related() purposes. Used by both the query construction code
    (compiler.get_related_selections()) and the model instance creation code
    (compiler.klass_info).

    Arguments:
     * field - the field to be checked
     * restricted - a boolean field, indicating if the field list has been
       manually restricted using a requested clause)
     * requested - The select_related() dictionary.
     * select_mask - the dictionary of selected fields.
     * reverse - boolean, True if we are checking a reverse select related
    FzField Ú.zM cannot be both deferred and traversed using select_related at the same time.TN)	Zremote_fieldZparent_linkZrelated_query_namerN   Únullr   ri   rh   Zobject_name)r^   Z
restrictedÚ	requestedZselect_maskÚreverser   r   r   Úselect_related_descend;  s.   
ÿþýüÿr    c                 C   sL   t dt| ƒd ƒD ]}t | d|… ¡}| |¡r#|| |d… f  S q	dS )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   Újoinrt   )Zlookup_partsÚannotationsÚnZlevel_n_lookupr   r   r   Úrefs_expressionb  s   
ÿr¦   c                    s,   ‡ fdd„}||ƒpt |ddƒo||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                    s*   ˆ j j| jkp| jˆ j  ¡ v pˆ |  ¡ v S r   )rh   Zconcrete_modelZget_parent_list)rk   ©ri   r   r   rR   w  s
   ÿ
ýz-check_rel_lookup_compatibility.<locals>.checkrj   FN)r&   ri   rh   )ri   Ztarget_optsr^   rR   r   r§   r   Úcheck_rel_lookup_compatibilityo  s   ÿr¨   c                   @   s@   e Zd ZdZeƒ dœdd„Zdd„ Zdd„ Zd	d
„ Zdd„ Z	dS )ÚFilteredRelationz7Specify custom filtering in the ON clause of SQL joins.©Ú	conditionc                C   s:   |st dƒ‚|| _d | _t|tƒst dƒ‚|| _g | _d S )Nzrelation_name cannot be empty.z*condition argument must be a Q() instance.)Ú
ValueErrorÚrelation_nameÚaliasr)   r   r«   rX   )r    r­   r«   r   r   r   r   �  s   

zFilteredRelation.__init__c                 C   s4   t || jƒstS | j|jko| j|jko| j|jkS r   )r)   r$   ÚNotImplementedr­   r®   r«   r1   r   r   r   Ú__eq__™  s   
ÿ
ýzFilteredRelation.__eq__c                 C   s,   t | j| jd�}| j|_| jd d … |_|S )Nrª   )r©   r­   r«   r®   rX   )r    Úcloner   r   r   r±   ¢  s   zFilteredRelation.clonec                 O   s   t dƒ‚)zz
        QuerySet.annotate() only accepts expression-like arguments
        (with a resolve_expression() method).
        z0FilteredRelation.resolve_expression() is unused.N)ÚNotImplementedError)r    r!   r"   r   r   r   r<   ¨  s   z#FilteredRelation.resolve_expressionc                 C   s&   |j }|j| jt| jƒd�}| |¡S )N)r;   )r:   Zbuild_filtered_relation_qr«   ÚsetrX   Úcompile)r    rP   Ú
connectionr:   Úwherer   r   r   Úas_sql¯  s   
zFilteredRelation.as_sqlN)
rT   rS   rZ   r[   r   r   r°   r±   r<   r·   r   r   r   r   r©   Œ  s    
	r©   )F)r[   ro   r|   ÚloggingÚcollectionsr   Zdjango.core.exceptionsr   Z	django.dbr   r   r   Zdjango.db.models.constantsr   Zdjango.utilsr   Ú	getLoggerrL   r
   r   ÚNoder   r]   rl   rr   r    r¦   r¨   r©   r   r   r   r   Ú<module>   s.    
þx)
g'