B
    ©0H[À/  ã               @   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   ú`C:\Users\HIRONO~1\AppData\Local\Temp\pip-install-6bm3nxem\django\django\db\models\query_utils.pyr      s   r   c             c   s*   | V  x|   ¡ D ]}t|ƒE d H  qW 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 )N)ÚlistÚdata)ÚselfZsqlÚparamsr   r   r   Ú__init__(   s    zQueryWrapper.__init__Nc             C   s   | j S )N)r   )r   ÚcompilerÚ
connectionr   r   r   Úas_sql+   s    zQueryWrapper.as_sql)NN)r   r   r	   r
   Zcontains_aggregater   r   r   r   r   r   r   !   s   r   c                   s^   e Zd ZdZdZdZeZ‡ 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ÚORc                s>   |  dd ¡}|  dd¡}tƒ jt|ƒt| ¡ ƒ ||d� d S )NÚ
_connectorÚ_negatedF)ÚchildrenÚ	connectorÚnegated)ÚpopÚsuperr   r   ÚsortedÚitems)r   ÚargsÚkwargsr    r!   )Ú	__class__r   r   r   9   s    z
Q.__init__c             C   sZ   t |tƒst|ƒ‚|s t | ¡S | s.t |¡S t| ƒƒ }||_| | |¡ | ||¡ |S )N)Ú
isinstancer   Ú	TypeErrorÚcopyÚdeepcopyÚtyper    Úadd)r   ÚotherÚconnÚobjr   r   r   Ú_combine>   s    



z
Q._combinec             C   s   |   || j¡S )N)r2   r   )r   r/   r   r   r   Ú__or__O   s    zQ.__or__c             C   s   |   || j¡S )N)r2   r   )r   r/   r   r   r   Ú__and__R   s    z	Q.__and__c             C   s$   t | ƒƒ }| | | j¡ | ¡  |S )N)r-   r.   r   Únegate)r   r1   r   r   r   Ú
__invert__U   s    
zQ.__invert__NTFc             C   s$   |j | ||dd�\}}| |¡ |S )NF)Úallow_joinsZ
split_subq)Z_add_qZpromote_joins)r   Úqueryr7   ÚreuseZ	summarizeZfor_saveZclauseZjoinsr   r   r   Úresolve_expression[   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rŽd| j
i}| jrœd|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   Údeconstructb   s    




zQ.deconstruct)NTNFF)r   r   r	   r
   r   r   r@   r   r2   r3   r4   r6   r:   rC   Ú__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 )N)Ú
field_name)r   rF   Úmodelr   r   r   r   x   s    zDeferredAttribute.__init__Nc             C   sj   |dkr| S |j }| | j| ¡| kr`|  || j¡}|dkrV|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__ÚgetrF   Ú_check_parent_chainZrefresh_from_dbÚgetattr)r   Úinstancer   r   Úvalr   r   r   Ú__get__{   s    
zDeferredAttribute.__get__c             C   s:   |j }| |¡}| |j¡}|jr6||kr6t||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_fieldZget_ancestor_linkrG   Úprimary_keyrL   Úattname)r   rM   ÚnameÚoptsÚfZ
link_fieldr   r   r   rK   �   s    
z%DeferredAttribute._check_parent_chain)N)r   r   r	   r
   r   rO   rK   r   r   r   r   rE   s   s   
rE   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 )N)Úget_lookupsrJ   )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)rI   rJ   )Ú.0Úparentr   r   r   ú
<listcomp>¤   s    z3RegisterLookupMixin.get_lookups.<locals>.<listcomp>)ÚinspectÚgetmroÚmerge_dicts)r   r\   r   r   r   rX   ¡   s    zRegisterLookupMixin.get_lookupsc             C   sN   ddl m} |  |¡}|d kr4t| dƒr4| j |¡S |d k	rJt||ƒsJd S |S )Nr   )ÚLookupÚoutput_field)Údjango.db.models.lookupsrc   rZ   Úhasattrrd   Ú
get_lookupÚ
issubclass)r   rY   rc   Úfoundr   r   r   rg   §   s    
zRegisterLookupMixin.get_lookupc             C   sN   ddl m} |  |¡}|d kr4t| dƒr4| j |¡S |d k	rJt||ƒsJd S |S )Nr   )Ú	Transformrd   )re   rj   rZ   rf   rd   Úget_transformrh   )r   rY   rj   ri   r   r   r   rk   °   s    
z!RegisterLookupMixin.get_transformc             C   s$   i }xt | ƒD ]}| |¡ qW |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dictsZmergedÚdr   r   r   rb   ¹   s    zRegisterLookupMixin.merge_dictsc             C   s    xt | ƒD ]}|j ¡  q
W d S )N)r   rX   Úcache_clear)r   r   r   r   r   Ú_clear_cached_lookupsÄ   s    z)RegisterLookupMixin._clear_cached_lookupsc             C   s4   |d kr|j }d| jkri | _|| j|< |  ¡  |S )Nr\   )rY   rI   r\   rp   )r   ÚlookuprY   r   r   r   Úregister_lookupÉ   s    

z#RegisterLookupMixin.register_lookupc             C   s   |dkr|j }| j|= dS )zn
        Remove given lookup from cls lookups. For use in tests only as it's
        not thread-safe.
        N)rY   r\   )r   rq   rY   r   r   r   Ú_unregister_lookupÓ   s    z&RegisterLookupMixin._unregister_lookup)N)N)r   r   r	   ÚclassmethodrZ   Ú	functoolsÚ	lru_cacherX   rg   rk   Ústaticmethodrb   rp   rr   rs   r   r   r   r   rW   ›   s   			rW   Fc             C   sŠ   | j s
dS | j jr|sdS |rD|r2|  ¡ |kr2dS |sD| j|krDdS |sR| jrRdS |r†| j|kr†|r†| j|kr†t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)
Zremote_fieldZparent_linkZrelated_query_namerT   ÚnullrS   r   rG   rP   Zobject_name)ÚfieldZ
restrictedÚ	requestedZload_fieldsÚreverser   r   r   Úselect_related_descendÞ   s"    

r|   c             C   sV   xPt dt| ƒd ƒD ]:}t | d|… ¡}||kr|| r|| | |d… fS qW 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)Fr   )Úranger>   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  ¡ kp(ˆ |  ¡ kS )N)rP   Zconcrete_modelZget_parent_list)rU   )rG   r   r   Úcheck  s    z-check_rel_lookup_compatibility.<locals>.checkrR   F)rL   rG   rP   )rG   Ztarget_optsry   r‚   r   )rG   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…   rA   )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 )N)r)   r(   r‡   rˆ   r…   )r   r/   r   r   r   Ú__eq__8  s    zFilteredRelation.__eq__c             C   s,   t | j| jd�}| j|_| jd d … |_|S )N)r…   )r„   r‡   r…   rˆ   rA   )r   Úcloner   r   r   rŠ   @  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   r&   r'   r   r   r   r:   F  s    z#FilteredRelation.resolve_expressionc             C   s&   |j }|j| jt| jƒd�}| |¡S )N)r9   )r8   Zbuild_filtered_relation_qr…   ÚsetrA   Úcompile)r   r   r   r8   Úwherer   r   r   r   M  s    zFilteredRelation.as_sqlN)
r   r   r	   r
   r   r   r‰   rŠ   r:   r   r   r   r   r   r„   +  s   
r„   )F)r
   r+   ru   r`   Úcollectionsr   Zdjango.db.models.constantsr   Zdjango.utilsr   r   Ú	Exceptionr   r   r   ÚNoder   rE   rW   r|   r�   rƒ   r„   r   r   r   r   Ú<module>   s"   
D(C
$