a
    xd>1                     @   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m	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G dd dee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FieldDoesNotExist
FieldError)
LOOKUP_SEP)tree)RemovedInDjango40WarningPathInfozGfrom_opts to_opts target_fields join_field m2m direct filtered_relationc                       s<   e Zd Zedd Zdd Z fddZ fddZ  ZS )	InvalidQueryTypec                 C   s   t tfS Nr   self r   T/var/www/html/Ranjet/env/lib/python3.9/site-packages/django/db/models/query_utils.py_subclasses   s    zInvalidQueryType._subclassesc                 C   s   t jdtdd d S )Nz\The InvalidQuery exception class is deprecated. Use FieldDoesNotExist or FieldError instead.   )category
stacklevel)warningswarnr   r   r   r   r   Z__warn   s
    zInvalidQueryType.__warnc                    s    |    t|| jpt |S r   )_InvalidQueryType__warn
isinstancer   super__instancecheck__)r   instance	__class__r   r   r   &   s    z"InvalidQueryType.__instancecheck__c                    s    |    t|| jpt |S r   )r   
issubclassr   r   __subclasscheck__)r   subclassr   r   r   r   *   s    z"InvalidQueryType.__subclasscheck__)	__name__
__module____qualname__propertyr   r   r   r   __classcell__r   r   r   r   r
      s
   
r
   c                   @   s   e Zd ZdS )InvalidQueryN)r    r!   r"   r   r   r   r   r%   /   s   r%   )	metaclassc                 c   s&   | V  |   D ]}t|E d H  qd S r   )__subclasses__
subclassesclsr   r   r   r   r(   3   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)r   __init__sorteditems)r   r.   r/   argskwargsr   r   r   r3   D   s    z
Q.__init__c                 C   sZ   t |tst||s t| S | s.t|S t|  }||_|| | ||| |S r   )r   r+   	TypeErrorcopydeepcopytyper1   add)r   otherconnobjr   r   r   _combineG   s    



z
Q._combinec                 C   s   |  || jS r   )r@   r-   r   r=   r   r   r   __or__X   s    zQ.__or__c                 C   s   |  || jS r   )r@   r,   rA   r   r   r   __and__[   s    z	Q.__and__c                 C   s$   t |  }|| | j |  |S r   )r;   r<   r,   negate)r   r?   r   r   r   
__invert__^   s    
zQ.__invert__c                 C   s&   |j | ||ddd\}}|| |S )NF)allow_joinsZ
split_subqZcheck_filterable)Z_add_qZpromote_joins)r   queryrF   reuseZ	summarizeZfor_saveZclauseZjoinsr   r   r   resolve_expressiond   s    

zQ.resolve_expressionc                 C   s   d| j j| j jf }|dr*|dd}di  }}t| jdkrnt| jd tsn| jd }|d |d i}n t	| j}| j
| jkrd| j
i}| jrd|d	< |||fS )
Nz%s.%szdjango.db.models.query_utilszdjango.db.modelsr      r   r.   Tr/   )r   r!   r    
startswithreplacelenr0   r   r+   tupler1   defaultr2   )r   pathr6   r7   childr   r   r   deconstructn   s    




zQ.deconstruct)NTNFF)r    r!   r"   __doc__r,   r-   rO   Zconditionalr3   r@   rB   rC   rE   rI   rR   r$   r   r   r   r   r+   9   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   rU   r   r   r   r3      s    zDeferredAttribute.__init__Nc                 C   s\   |du r| S |j }| jj}||vrT| |}|du rL|j|gd t||}|||< || S )zx
        Retrieve and caches the value from the datastore on the first lookup.
        Return the cached value.
        N)fields)__dict__rU   attname_check_parent_chainZrefresh_from_dbgetattr)r   r   r*   data
field_namevalr   r   r   __get__   s    

zDeferredAttribute.__get__c                 C   s6   |j }|| jj}| jjr2| j|kr2t||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_linkrU   modelprimary_keyrZ   rX   )r   r   optsZ
link_fieldr   r   r   rY      s
    z%DeferredAttribute._check_parent_chain)N)r    r!   r"   rS   r3   r^   rY   r   r   r   r   rT      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_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)rW   re   ).0parentr   r   r   
<listcomp>       z3RegisterLookupMixin.get_lookups.<locals>.<listcomp>)inspectgetmromerge_dicts)r*   ri   r   r   r   rd      s    zRegisterLookupMixin.get_lookupsc                 C   sN   ddl m} | |}|d u r4t| dr4| j|S |d urJt||sJd S |S )Nr   )Lookupoutput_field)django.db.models.lookupsrq   rg   hasattrrr   
get_lookupr   )r   rf   rq   foundr   r   r   ru      s    
zRegisterLookupMixin.get_lookupc                 C   sN   ddl m} | |}|d u r4t| dr4| j|S |d urJt||sJd S |S )Nr   )	Transformrr   )rs   rw   rg   rt   rr   get_transformr   )r   rf   rw   rv   r   r   r   rx      s    
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)Zdictsmergeddr   r   r   rp      s    zRegisterLookupMixin.merge_dictsc                 C   s   t | D ]}|j  qd S r   )r(   rd   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 )Nri   )rf   rW   ri   r~   r*   lookuprf   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)rf   ri   r   r   r   r   _unregister_lookup   s    z&RegisterLookupMixin._unregister_lookup)N)N)r    r!   r"   classmethodrg   	functools	lru_cacherd   ru   rx   staticmethodrp   r~   r   r   r   r   r   r   rc      s   

		


	rc   Fc                 C   s   | j s
dS | j jr|sdS |rD|r2|  |vr2dS |sD| j|vrDdS |sR| jrRdS |r| j|vr|r| j|v rd| jjj| jf }t	|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)
Zremote_fieldZparent_linkZrelated_query_namenamenullrX   r`   r_   Zobject_namer   )rU   Z
restricted	requestedZ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.
    rJ   r   N)Fr   )rangerM   r   join)Zlookup_partsannotationsnZ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_   Zconcrete_modelZget_parent_list)rb   r`   r   r   check#  s
    
z-check_rel_lookup_compatibility.<locals>.checkra   F)rZ   r`   r_   )r`   Ztarget_optsrU   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   rP   )r   r   r   r   r   r   r3   ;  s    
zFilteredRelation.__init__c                 C   s4   t || jstS | j|jko2| j|jko2| j|jkS r   )r   r   NotImplementedr   r   r   rA   r   r   r   __eq__E  s    

zFilteredRelation.__eq__c                 C   s,   t | j| jd}| j|_| jd d  |_|S )Nr   )r   r   r   r   rP   )r   cloner   r   r   r   N  s    zFilteredRelation.clonec                 O   s   t ddS )zz
        QuerySet.annotate() only accepts expression-like arguments
        (with a resolve_expression() method).
        z0FilteredRelation.resolve_expression() is unused.N)NotImplementedError)r   r6   r7   r   r   r   rI   T  s    z#FilteredRelation.resolve_expressionc                 C   s&   |j }|j| jt| jd}||S )N)rH   )rG   Zbuild_filtered_relation_qr   setrP   compile)r   compiler
connectionrG   wherer   r   r   as_sql[  s    zFilteredRelation.as_sqlN)
r    r!   r"   rS   r+   r3   r   r   rI   r   r   r   r   r   r   8  s   
	r   )F)rS   r9   r   rn   r   collectionsr   Zdjango.core.exceptionsr   r   Zdjango.db.models.constantsr   Zdjango.utilsr   Zdjango.utils.deprecationr   r	   r;   r
   	Exceptionr%   r(   Noder+   rT   rc   r   r   r   r   r   r   r   r   <module>   s(   
F(C
%