o
    ˜¨ÊhM4  ã                   @   sÚ   d Z ddl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 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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)Ú
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   úN/var/www/html/env/lib/python3.10/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   1   s
   
ýz
Q.__init__c                 C   sœ   t |tƒst|ddƒdu st|ƒ‚| s!t|dƒr| ¡ S t |¡S t |tƒr8|s8|  ¡ \}}}t| ƒ|i |¤ŽS t| ƒƒ }||_| 	| |¡ | 	||¡ |S )NÚconditionalFTÚcopy)
Ú
isinstancer   ÚgetattrÚ	TypeErrorÚhasattrr%   ÚdeconstructÚtyper   Úadd)r   ÚotherÚconnÚ_r    r!   Úobjr   r   r   Ú_combine8   s   
z
Q._combinec                 C   ó   |   || j¡S r
   )r1   r   ©r   r-   r   r   r   Ú__or__H   ó   zQ.__or__c                 C   r2   r
   )r1   r   r3   r   r   r   Ú__and__K   r5   z	Q.__and__c                 C   r2   r
   )r1   r   r3   r   r   r   Ú__xor__N   r5   z	Q.__xor__c                 C   s$   t | ƒƒ }| | | j¡ | ¡  |S r
   )r+   r,   r   Únegate)r   r0   r   r   r   Ú
__invert__Q   s   
zQ.__invert__c                 C   s&   |j | ||ddd�\}}| |¡ |S )NF)Úallow_joinsÚ
split_subqÚcheck_filterable)Ú_add_qÚpromote_joins)r   Úqueryr:   ÚreuseÚ	summarizeÚfor_saveÚclauseÚjoinsr   r   r   Úresolve_expressionW   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&   Útupler)   rG   )r   Úchildr   r   r   rG   f   s   €


ùz	Q.flattenc              
   C   sÌ   ddl m} ddlm} ddlm} |dƒ}| ¡ D ]\}}t|dƒs'||ƒ}|j||dd� q| |d	ƒd
¡ | 	| ¡ |j
|d�}	z|	 |¡duW S  tye }
 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   )ÚValue)ÚQuery)ÚSINGLENrE   F)ÚselectrF   Ú_check)Úusingz.Got a database error calling check() on %r: %sT)Údjango.db.modelsrJ   Údjango.db.models.sqlrK   Údjango.db.models.sql.constantsrL   r   r)   Úadd_annotationÚadd_qÚget_compilerÚexecute_sqlr   ÚloggerÚwarning)r   ÚagainstrO   rJ   rK   rL   r?   ÚnameÚvalueÚcompilerÚer   r   r   Úchecku   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ÚreplacerH   r   r   Údefaultr   )r   Úpathr    r!   r   r   r   r*   Ž   s   



zQ.deconstruct)NTNFF)r`   r_   Ú__qualname__Ú__doc__r   r   r   rc   r$   r   r1   r4   r6   r7   r9   rE   rG   r   r^   r*   Ú__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   ri   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__ri   ÚattnameÚ_check_parent_chainÚ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)Ú_metaÚget_ancestor_linkri   ÚmodelÚprimary_keyr'   rl   )r   ro   ÚoptsÚ
link_fieldr   r   r   rm   ·   s
   z%DeferredAttribute._check_parent_chainr
   )r`   r_   re   rf   r   rs   rm   r   r   r   r   rh   ›   s
    
rh   c                   @   st   e Zd Zedd„ ƒZeejdd�dd„ ƒƒZdd„ Zd	d
„ Z	e
dd„ ƒZedd„ ƒZeddd„ƒZeddd„ƒ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)rk   r|   )Ú.0Úparentr   r   r   Ú
<listcomp>Ì   s    ÿz3RegisterLookupMixin.get_lookups.<locals>.<listcomp>)ÚinspectÚgetmroÚmerge_dicts)r   r€   r   r   r   r{   É   s   ÿ
zRegisterLookupMixin.get_lookupsc                 C   óN   ddl m} |  |¡}|d u rt| dƒr| j |¡S |d ur%t||ƒs%d S |S )Nr   )ÚLookupÚoutput_field)Údjango.db.models.lookupsrˆ   r~   r)   r‰   Ú
get_lookupÚ
issubclass)r   r}   rˆ   Úfoundr   r   r   r‹   Ñ   ó   
zRegisterLookupMixin.get_lookupc                 C   r‡   )Nr   )Ú	Transformr‰   )rŠ   r�   r~   r)   r‰   Úget_transformrŒ   )r   r}   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'.
        )ÚreversedÚupdate)Ú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_lookupsð   s   ÿz)RegisterLookupMixin._clear_cached_lookupsc                 C   s4   |d u r|j }d| jvri | _|| j|< |  ¡  |S )Nr€   )r}   rk   r€   r—   ©r   Úlookupr}   r   r   r   Úregister_lookupõ   s   

z#RegisterLookupMixin.register_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)r}   r€   r—   r˜   r   r   r   Ú_unregister_lookupÿ   s   z&RegisterLookupMixin._unregister_lookupr
   )r`   r_   re   Úclassmethodr~   Ú	functoolsÚ	lru_cacher{   r‹   r�   Ústaticmethodr†   r—   rš   r›   r   r   r   r   rz   Ä   s     






	rz   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| j|vrE|rE| j|v rEd| jjj| jf }t	|ƒ‚dS )ap  
    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.
     * load_fields - the set of fields to be loaded on this model
     * reverse - boolean, True if we are checking a reverse select related
    FzXField %s.%s cannot be both deferred and traversed using select_related at the same time.T)
Úremote_fieldÚparent_linkÚrelated_query_namerZ   Únullrl   rv   rt   Úobject_namer   )ri   Ú
restrictedÚ	requestedÚload_fieldsÚreverseÚmsgr   r   r   Úselect_related_descend  s&   

ýrª   c                 C   sV   t dt| ƒd ƒD ]}t | d|… ¡}||v r(|| 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.
    rF   r   N)Fr   )ÚrangeÚlenr   Újoin)Úlookup_partsÚannotationsÚnÚlevel_n_lookupr   r   r   Úrefs_expression0  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
   )rt   Úconcrete_modelÚget_parent_list)rx   ©rv   r   r   r^   E  s
   ÿ
ýz-check_rel_lookup_compatibility.<locals>.checkrw   F)r'   rv   rt   )rv   Útarget_optsri   r^   r   rµ   r   Úcheck_rel_lookup_compatibility=  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º   rd   )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º   r3   r   r   r   Ú__eq__g  s   
ÿ
ýzFilteredRelation.__eq__c                 C   s,   t | j| jd�}| j|_| jd d … |_|S )Nr¹   )r¸   r¼   rº   r½   rd   )r   Úcloner   r   r   rÀ   p  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.)ÚNotImplementedError)r   r    r!   r   r   r   rE   v  s   z#FilteredRelation.resolve_expressionc                 C   s&   |j }|j| jt| jƒd�}| |¡S )N)r@   )r?   Úbuild_filtered_relation_qrº   Úsetrd   Úcompile)r   r\   Ú
connectionr?   Úwherer   r   r   Úas_sql}  s   
zFilteredRelation.as_sqlN)
r`   r_   re   rf   r   r   r¿   rÀ   rE   rÇ   r   r   r   r   r¸   Z  s    
	r¸   )F)rf   r%   r�   r„   ÚloggingÚcollectionsr   Údjango.core.exceptionsr   Ú	django.dbr   r   Údjango.db.models.constantsr   Údjango.utilsr   Ú	getLoggerrW   r	   r   ÚNoder   rh   rz   rª   r²   r·   r¸   r   r   r   r   Ú<module>   s.    
þw)
G%