U
    R+|jŒ<  ã                   @   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   údc:\users\snmko\desktop\web_content\django_cbt\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eeef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                   sZ   || j kr8d dd„ | j dd … D ƒ¡}td|› d�ƒ‚tƒ j|t| ¡ ƒ•||d� d S )Nz, c                 s   s   | ]}|›V  qd S r   r   )Ú.0Úconnr   r   r   Ú	<genexpr>3   s     zQ.__init__.<locals>.<genexpr>é   z_connector must be one of z
, or None.)ÚchildrenÚ	connectorÚnegated)Ú
connectorsÚjoinÚ
ValueErrorÚsuperÚ__init__ÚsortedÚitems)Úselfr   r   ÚargsÚkwargsZconnector_reprs©Ú	__class__r   r   r$   1   s    
ýz
Q.__init__c                 C   sb   t |ddƒdkrt|ƒ‚| s$| ¡ S |s:t|tƒr:|  ¡ S | j|d�}| | |¡ | ||¡ |S )NÚconditionalF)r   )ÚgetattrÚ	TypeErrorÚcopyÚ
isinstancer   ÚcreateÚadd)r'   Úotherr   Úobjr   r   r   Ú_combine;   s    z
Q._combinec                 C   s   |   || j¡S r   )r5   r   ©r'   r3   r   r   r   Ú__or__H   s    zQ.__or__c                 C   s   |   || j¡S r   )r5   r   r6   r   r   r   Ú__and__K   s    z	Q.__and__c                 C   s   |   || j¡S r   )r5   r   r6   r   r   r   Ú__xor__N   s    z	Q.__xor__c                 C   s   |   ¡ }| ¡  |S r   )r/   Únegate)r'   r4   r   r   r   Ú
__invert__Q   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'   Úqueryr<   Úreuser=   Zfor_saveZclauseZjoinsr   r   r   Úresolve_expressionV   s    ú

zQ.resolve_expressionc                 c   sH   | V  | j D ]6}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.
        r   ÚflattenN)r   r0   ÚtupleÚhasattrrA   )r'   Úchildr   r   r   rA   f   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	� qD| |d
ƒd¡ t| jjr¨| t|| d|ƒ d�ƒ¡ n
| | ¡ |j|d�}z| |¡dk	W S  tk
�r } zt d| |¡ W Y ¢dS d}~X Y nX dS )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.modelsrE   rF   Zdjango.db.models.functionsrG   Zdjango.db.models.sqlrH   Zdjango.db.models.sql.constantsrI   r&   rC   Zadd_annotationr   ÚfeaturesZsupports_comparing_boolean_exprZadd_qr   Zget_compilerZexecute_sqlr   ÚloggerÚwarning)r'   ZagainstrM   rE   rF   rG   rH   rI   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rN| j|d< | j	r\d|d< |||fS )Nz%s.%szdjango.db.models.query_utilsr	   r   Tr   )
r+   Ú
__module__Ú__name__Ú
startswithÚreplacerB   r   r   Údefaultr   )r'   Úpathr(   r)   r   r   r   Údeconstruct’   s    


zQ.deconstruct)NTNFF)rW   rV   Ú__qualname__Ú__doc__r   r   r   rZ   r,   r    r$   r5   r7   r8   r9   r;   r@   rA   r   rU   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'   ra   r   r   r   r$   ¥   s    zDeferredAttribute.__init__Nc                 C   sT   |dkr| S |j }| jj}||krL|  |¡}|dkrD|j|gd� n|||< || S )zx
        Retrieve and caches the value from the datastore on the first lookup.
        Return the cached value.
        N)Úfields)Ú__dict__ra   Ú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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_linkra   ÚmodelÚprimary_keyr-   rd   )r'   rf   ÚoptsZ
link_fieldr   r   r   re   »   s
    z%DeferredAttribute._check_parent_chain)N)rW   rV   r]   r^   r$   rj   re   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'   rp   rq   r   r   r   r$   Î   s    z!class_or_instance_method.__init__c                 C   s$   |d krt  | j|¡S t  | j|¡S r   )Ú	functoolsÚpartialrp   rq   )r'   rf   Úownerr   r   r   rj   Ò   s    z class_or_instance_method.__get__N)rW   rV   r]   r^   r$   rj   r   r   r   r   ro   È   s   ro   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)rc   rw   )r   Úparentr   r   r   Ú
<listcomp>Þ   s    z9RegisterLookupMixin.get_class_lookups.<locals>.<listcomp>)ÚinspectÚgetmroÚmerge_dicts)r   r{   r   r   r   Úget_class_lookupsÜ   s    ÿz%RegisterLookupMixin.get_class_lookupsc                 C   s$   |   ¡ }t| dd ƒ }r ||–S |S ©NÚinstance_lookups)r�   r-   )r'   r{   rƒ   r   r   r   Úget_instance_lookupsã   s    z(RegisterLookupMixin.get_instance_lookupsc                 C   sN   ddl m} |  |¡}|d kr4t| dƒr4| j |¡S |d k	rJt||ƒsJd S |S )Nr   )ÚLookuprL   )Údjango.db.models.lookupsr…   ry   rC   rL   Ú
get_lookupÚ
issubclass)r'   rx   r…   Úfoundr   r   r   r‡   ì   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   )Ú	TransformrL   )r†   rŠ   ry   rC   rL   Úget_transformrˆ   )r'   rx   rŠ   r‰   r   r   r   r‹   ö   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   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 kr|j }d| jkri | _|| j|< |  ¡  |S )Nr{   )rx   rc   r{   r‘   ©r   Úlookuprx   r   r   r   Úregister_class_lookup  s    

z)RegisterLookupMixin.register_class_lookupc                 C   s,   |d kr|j }d| jkri | _|| j|< |S r‚   )rx   rc   rƒ   ©r'   r“   rx   r   r   r   Úregister_instance_lookup  s    

z,RegisterLookupMixin.register_instance_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)rx   r{   r‘   r’   r   r   r   Ú_unregister_class_lookup&  s    z,RegisterLookupMixin._unregister_class_lookupc                 C   s   |dkr|j }| j|= dS )zs
        Remove given lookup from instance lookups. For use in tests only as
        it's not thread-safe.
        N)rx   rƒ   r•   r   r   r   Ú_unregister_instance_lookup0  s    z/RegisterLookupMixin._unregister_instance_lookup)N)N)N)N)rW   rV   r]   ry   rr   Ú	lru_cacher�   r„   ro   rv   Úclassmethodr‡   r‹   Ústaticmethodr€   r‘   r”   r–   Zregister_lookupr—   r˜   Z_unregister_lookupr   r   r   r   ru   Ø   s4   








	
 ÿ


	 ÿru   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Š|rŠ| j|krŠ| |krŠt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.T)	Zremote_fieldZparent_linkZrelated_query_namerQ   Únullr   rl   rk   Zobject_name)ra   Z
restrictedÚ	requestedZselect_maskÚreverser   r   r   Úselect_related_descend?  s.    
ÿþýüÿr    c                 C   sL   t dt| ƒd ƒD ]4}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   r!   rw   )Zlookup_partsÚannotationsÚnZlevel_n_lookupr   r   r   Úrefs_expressionf  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 r   )rk   Zconcrete_modelZget_parent_list)rn   ©rl   r   r   rU   {  s
    ÿ
ýz-check_rel_lookup_compatibility.<locals>.checkrm   F)r-   rl   rk   )rl   Ztarget_optsra   rU   r   r¦   r   Úcheck_rel_lookup_compatibilitys  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.)r"   Úrelation_nameÚaliasr0   r   rª   r[   )r'   r«   rª   r   r   r   r$   “  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   )r0   r+   ÚNotImplementedr«   r¬   rª   r6   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¬   r[   )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@   ¬  s    z#FilteredRelation.resolve_expressionc                 C   s&   |j }|j| jt| jƒd�}| |¡S )N)r?   )r>   Zbuild_filtered_relation_qrª   Úsetr[   Úcompile)r'   rS   Ú
connectionr>   Úwherer   r   r   Úas_sql³  s    zFilteredRelation.as_sqlN)
rW   rV   r]   r^   r   r$   r®   r¯   r@   rµ   r   r   r   r   r¨   �  s   
	r¨   )F)r^   rr   r~   ÚloggingÚcollectionsr   Zdjango.core.exceptionsr   Z	django.dbr   r   r   Zdjango.db.models.constantsr   Zdjango.utilsr   Ú	getLoggerrO   r
   r   ÚNoder   r`   ro   ru   r    r¥   r§   r¨   r   r   r   r   Ú<module>   s,   
þ|)g
'