o
    uvXj�/  ã                   @   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	 eddƒZ
G dd	„ d	eƒZd
d„ ZG d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)Ú
LOOKUP_SEP)ÚtreeÚPathInfozGfrom_opts to_opts target_fields join_field m2m direct filtered_relationc                   @   s   e Zd ZdZdS )ÚInvalidQueryz?The query passed to raw() isn't a safe query to use with raw().N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__© r   r   úY/var/www/html/myproject/venv/lib/python3.10/site-packages/django/db/models/query_utils.pyr      s    r   c                 c   s(   � | V  |   ¡ D ]	}t|ƒE d H  qd S ©N)Ú__subclasses__Ú
subclasses©ÚclsÚsubclassr   r   r   r      s
   €ÿr   c                   @   s&   e Zd ZdZdZdd„ Zddd„ZdS )	ÚQueryWrapperz¢
    A type that indicates the contents are an SQL fragment and the associate
    parameters. Can be used to pass opaque data to a where-clause, for example.
    Fc                 C   s   |t |ƒf| _d S r   )ÚlistÚdata)ÚselfÚsqlÚparamsr   r   r   Ú__init__(   s   zQueryWrapper.__init__Nc                 C   s   | j S r   )r   )r   ÚcompilerÚ
connectionr   r   r   Úas_sql+   s   zQueryWrapper.as_sql)NN)r   r   r	   r
   Úcontains_aggregater   r   r   r   r   r   r   !   s
    r   c                       sj   e 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d„Zdd„ Z‡  ZS )ÚQze
    Encapsulate filters as objects that can then be combined logically (using
    `&` and `|`).
    ÚANDÚORTNF)Ú
_connectorÚ_negatedc                   s&   t ƒ jg |¢t| ¡ ƒ¢||d� d S )N)ÚchildrenÚ	connectorÚnegated)Úsuperr   ÚsortedÚitems)r   r!   r"   ÚargsÚkwargs©Ú	__class__r   r   r   :   s   &z
Q.__init__c                 C   sZ   t |tƒs	t|ƒ‚|st | ¡S | st |¡S t| ƒƒ }||_| | |¡ | ||¡ |S r   )Ú
isinstancer   Ú	TypeErrorÚcopyÚdeepcopyÚtyper$   Úadd)r   ÚotherÚconnÚobjr   r   r   Ú_combine=   s   



z
Q._combinec                 C   ó   |   || j¡S r   )r6   r    ©r   r3   r   r   r   Ú__or__N   ó   zQ.__or__c                 C   r7   r   )r6   r   r8   r   r   r   Ú__and__Q   r:   z	Q.__and__c                 C   s$   t | ƒƒ }| | | j¡ | ¡  |S r   )r1   r2   r   Únegate)r   r5   r   r   r   Ú
__invert__T   s   
zQ.__invert__c                 C   s$   |j | ||dd�\}}| |¡ |S )NF)Úallow_joinsÚ
split_subq)Ú_add_qÚpromote_joins)r   Úqueryr>   ÚreuseÚ	summarizeÚfor_saveÚclauseÚjoinsr   r   r   Úresolve_expressionZ   s   
zQ.resolve_expressionc                 C   s¦   d| j j| j jf }| d¡r| dd¡}di }}t| jƒdkr7t| jd tƒs7| jd }|d |d i}nt	| jƒ}| j
| jkrGd| j
i}| jrNd|d	< |||fS )
Nz%s.%szdjango.db.models.query_utilszdjango.db.modelsr   é   r   r!   Tr"   )r,   r   r   Ú
startswithÚreplaceÚlenr#   r-   r   Útupler$   Údefaultr%   )r   Úpathr)   r*   Úchildr   r   r   Údeconstructa   s   





zQ.deconstruct)NTNFF)r   r   r	   r
   r   r    rN   Úconditionalr   r6   r9   r;   r=   rH   rQ   Ú__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_name)r   rU   r   r   r   r   w   s   
zDeferredAttribute.__init__Nc                 C   sj   |du r| S |j }| | j| ¡| u r0|  || j¡}|du r+|j| jgd� t|| jƒ}||| j< || j S )zx
        Retrieve and caches the value from the datastore on the first lookup.
        Return the cached value.
        N)Úfields)Ú__dict__ÚgetrU   Ú_check_parent_chainÚrefresh_from_dbÚgetattr)r   Úinstancer   r   Úvalr   r   r   Ú__get__z   s   

zDeferredAttribute.__get__c                 C   s:   |j }| |¡}| |j¡}|jr||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_fieldÚget_ancestor_linkÚmodelÚprimary_keyr[   Úattname)r   r\   ÚnameÚoptsÚfÚ
link_fieldr   r   r   rY   Œ   s   
z%DeferredAttribute._check_parent_chainr   )r   r   r	   r
   r   r^   rY   r   r   r   r   rT   r   s
    
rT   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_lookupsrX   )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)rW   rX   )Ú.0Úparentr   r   r   Ú
<listcomp>£   s    z3RegisterLookupMixin.get_lookups.<locals>.<listcomp>)ÚinspectÚgetmroÚmerge_dicts)r   rn   r   r   r   rj       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.lookupsrv   rl   Úhasattrrw   Ú
get_lookupÚ
issubclass)r   rk   rv   Úfoundr   r   r   rz   ¦   ó   
zRegisterLookupMixin.get_lookupc                 C   ru   )Nr   )Ú	Transformrw   )rx   r~   rl   ry   rw   Úget_transformr{   )r   rk   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   rt   ¸   s   zRegisterLookupMixin.merge_dictsc                 C   s   t | ƒD ]}|j ¡  qd S r   )r   rj   Ú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 )Nrn   )rk   rW   rn   r†   ©r   Úlookuprk   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)rk   rn   r‡   r   r   r   Ú_unregister_lookupÒ   s   z&RegisterLookupMixin._unregister_lookupr   )r   r   r	   Úclassmethodrl   Ú	functoolsÚ	lru_cacherj   rz   r   Ústaticmethodrt   r†   r‰   rŠ   r   r   r   r   ri   š   s     

		


	ri   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 |rC| j|vrC|rC| j|v rCtd| jjj	| jf ƒ‚dS )au  
    Return True if this field should be used to descend deeper for
    select_related() purposes. Used by both the query construction code
    (sql.query.fill_related_selections()) and the model instance creation code
    (query.get_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_namere   Únullrd   r   rb   r_   Úobject_name)ÚfieldÚ
restrictedÚ	requestedÚload_fieldsÚreverser   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.
    rI   r   N)Fr   )ÚrangerL   r   Újoin)Úlookup_partsÚannotationsÚnÚlevel_n_lookupr   r   r   Úrefs_expression  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   )r_   Úconcrete_modelÚget_parent_list)rf   ©rb   r   r   Úcheck  s
   ÿ
ýz-check_rel_lookup_compatibility.<locals>.checkrc   F)r[   rb   r_   )rb   Útarget_optsr”   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©   rO   )r   r«   r©   r   r   r   r   -  s   

zFilteredRelation.__init__c                 C   s0   t || jƒo| j|jko| j|jko| j|jkS r   )r-   r,   r«   r¬   r©   r8   r   r   r   Ú__eq__7  s   
ÿ
þ
üzFilteredRelation.__eq__c                 C   s,   t | j| jd�}| j|_| jd d … |_|S )Nr¨   )r§   r«   r©   r¬   rO   )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.)ÚNotImplementedError)r   r)   r*   r   r   r   rH   E  s   z#FilteredRelation.resolve_expressionc                 C   s&   |j }|j| jt| jƒd�}| |¡S )N)rC   )rB   Úbuild_filtered_relation_qr©   ÚsetrO   Úcompile)r   r   r   rB   Úwherer   r   r   r   L  s   
zFilteredRelation.as_sqlN)
r   r   r	   r
   r   r   r­   r®   rH   r   r   r   r   r   r§   *  s    
r§   )F)r
   r/   rŒ   rr   Úcollectionsr   Údjango.db.models.constantsr   Údjango.utilsr   r   Ú	Exceptionr   r   r   ÚNoder   rT   ri   r™   r    r¦   r§   r   r   r   r   Ú<module>   s$    
C(
C$