a
    xd6                     @   sJ  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	m
Z
 d dlmZmZ d dlmZ G dd	 d	eZG d
d dZG dd deeZG dd dZG dd deejZG dd dZG dd deejZG dd dZG dd deeZG dd dZG dd deejZG dd dejZG d d! d!ZG d"d# d#eejZdS )$    N)ObjectDoesNotExist)
connectionmodels)
LOOKUP_SEP)OneToOneFieldOneToOneRel)ModelIterableQuerySet)Joinc                   @   s   e Zd Zdd ZdS )InheritanceIterablec           	      c   s   | j }t|}t|ddrt|jj }t|jt	dd}|D ]z}d }|D ]}|
||}|rJ qdqJ|sl|}t|ddr|jD ]}t||t|| q~|D ]}t||t|| q|V  q>n
|E d H  d S )N
subclassesFT)keyreverse
_annotated)querysetr   getattrtuplequeryextrakeyssortedr   len_get_sub_obj_recurser   setattr)	selfr   iterextrasr   objZsub_objsk r    L/var/www/html/Ranjet/env/lib/python3.9/site-packages/model_utils/managers.py__iter__   s(    

zInheritanceIterable.__iter__N)__name__
__module____qualname__r"   r    r    r    r!   r      s   r   c                       sn   e Zd Z fddZdd Z fddZd fd	d
	Z fddZdddZdddZ	dd Z
dd Z  ZS )InheritanceQuerySetMixinc                    s   t  j|i | t| _d S N)super__init__r   Z_iterable_classr   argskwargs	__class__r    r!   r)   *   s    z!InheritanceQuerySetMixin.__init__c           
      G   s   d }| j | j|d}|s|}nbg }|D ]T}|| ju r6q&t|tfsP| j||d}||v rd|| q&td|d|q&|}| j	j
}|r| j
| }n| }t|t}t|j	j
t}	|r|	r|j	j
| ||_|S )Nlevelsz3{!r} is not in the discovered subclasses, tried: {}z, )_get_subclasses_recursemodel
isinstancestr_get_ancestors_pathappend
ValueErrorformatjoinr   Zselect_relateddictupdater   )
r   r   r0   Zcalculated_subclassesZverified_subclassessubclassZprevious_select_relatednew_qsZprevious_is_dictZnew_is_dictr    r    r!   select_subclasses.   s@    


z*InheritanceQuerySetMixin.select_subclassesc                    sH   i }dD ]}t | |rt| |||< qt jf i |}|j| |S N)r   r   )hasattrr   r(   _chain__dict__r;   )r   r,   r;   nameZchainedr-   r    r!   rA   X   s    
zInheritanceQuerySetMixin._chainNFc                    s4   t   }dD ] }t| |rt||t| | q|S r?   )r(   _cloner@   r   r   )r   klasssetupr,   qsrC   r-   r    r!   rD   b   s
    

zInheritanceQuerySetMixin._clonec                    s2   t  j|i |}dd |D t|  |_|S )Nc                 S   s   g | ]
}|j qS r    )Zdefault_alias).0ar    r    r!   
<listcomp>k       z5InheritanceQuerySetMixin.annotate.<locals>.<listcomp>)r(   annotatelistr   r   )r   r+   r,   Zqsetr-   r    r!   rL   i   s    z!InheritanceQuerySetMixin.annotatec                    s   dd  j  D } fdd|D }g }|r6|d8 }|D ]L}|sJ|du rx| j|jj|dD ]}|| t |  q\||  q:|S )z
        Given a Model class, find all related objects, exploring children
        recursively, returning a `list` of strings representing the
        relations for select_related
        c                 S   s   g | ]}t |tr|qS r    )r3   r   )rH   fr    r    r!   rJ   t   s   
zDInheritanceQuerySetMixin._get_subclasses_recurse.<locals>.<listcomp>c                    s<   g | ]4}t |jtrt|jj r |jjur|jr|qS r    )r3   fieldr   
issubclassr2   parent_link)rH   relr2   r    r!   rJ   x   s      Nr/   )_metaZ
get_fieldsr1   rO   r2   r6   get_accessor_namer   )r   r2   r0   Zrelated_objectsZrelsr   rR   r<   r    rS   r!   r1   n   s&    

z0InheritanceQuerySetMixin._get_subclasses_recursec                 C   s   t || jstd|| jg }|j| j}|r<|d8 }|dur|j}|d|  |sf|du r||j}|j| j}q<d}q<t	
|S )z
        Serves as an opposite to _get_subclasses_recurse, instead walking from
        the Model class up the Model's ancestry and constructing the desired
        select_related string backwards.
        z{!r} is not a subclass of {!r}rT   Nr   )rP   r2   r7   r8   rU   Zget_ancestor_linkZremote_fieldinsertrV   r   r9   )r   r2   r0   ZancestryrQ   relatedZparent_modelr    r    r!   r5      s$    z,InheritanceQuerySetMixin._get_ancestors_pathc                 C   sP   | t\}}}zt||}W n ty2   Y d S 0 |rH| ||}|S |S d S r'   )	partitionr   r   r   r   )r   r   r   rR   _nodechildr    r    r!   r      s    z-InheritanceQuerySetMixin._get_sub_obj_recursec                 O   s   |   j|i |S r'   )r>   getr*   r    r    r!   get_subclass   s    z%InheritanceQuerySetMixin.get_subclass)NF)N)N)r#   r$   r%   r)   r>   rA   rD   rL   r1   r5   r   r^   __classcell__r    r    r-   r!   r&   )   s   *


r&   c                   @   s   e Zd Zdd ZdS )InheritanceQuerySetc              	      sV   g }|D ]2 | dd fdd jj D  d  q| j| jd|gdS )zQ
        Fetch only objects that are instances of the provided model(s).
        (z AND c                    s   g | ]}d   jj|jqS )z"{}"."{}" IS NOT NULL)r8   rU   db_tableZattname)rH   rO   rS   r    r!   rJ      s
   z3InheritanceQuerySet.instance_of.<locals>.<listcomp>)z OR )where)r6   r9   rU   parentsvaluesr>   r   )r   r   Zwhere_queriesr    rS   r!   instance_of   s    
zInheritanceQuerySet.instance_ofN)r#   r$   r%   rg   r    r    r    r!   r`      s   r`   c                   @   s0   e Zd ZeZdd Zdd Zdd Zdd Zd	S )
InheritanceManagerMixinc                 C   s   |  | jS r'   )_queryset_classr2   r   r    r    r!   get_queryset   s    z$InheritanceManagerMixin.get_querysetc                 G   s   |   j| S r'   )rk   r>   )r   r   r    r    r!   r>      s    z)InheritanceManagerMixin.select_subclassesc                 O   s   |   j|i |S r'   )rk   r^   r*   r    r    r!   r^      s    z$InheritanceManagerMixin.get_subclassc                 G   s   |   j| S r'   )rk   rg   )r   r   r    r    r!   rg      s    z#InheritanceManagerMixin.instance_ofN)	r#   r$   r%   r`   ri   rk   r>   r^   rg   r    r    r    r!   rh      s
   rh   c                   @   s   e Zd ZdS )InheritanceManagerNr#   r$   r%   r    r    r    r!   rl      s   rl   c                       s0   e Zd Z fddZdd Z fddZ  ZS )QueryManagerMixinc                    s6   |r|d | _ ntjf i || _ d | _t   d S )Nr   )_qr   Q	_order_byr(   r)   r*   r-   r    r!   r)      s
    zQueryManagerMixin.__init__c                 G   s
   || _ | S r'   )rq   )r   r+   r    r    r!   order_by   s    zQueryManagerMixin.order_byc                    s,   t   | j}| jd ur(|j| j S |S r'   )r(   rk   filterro   rq   rr   )r   rG   r-   r    r!   rk      s    
zQueryManagerMixin.get_queryset)r#   r$   r%   r)   rr   rk   r_   r    r    r-   r!   rn      s   rn   c                   @   s   e Zd ZdS )QueryManagerNrm   r    r    r    r!   rt      s   rt   c                   @   s   e Zd ZdZdd ZdS )SoftDeletableQuerySetMixinzr
    QuerySet for SoftDeletableModel. Instead of removing instance sets
    its ``is_removed`` field to True.
    c                 C   s   | j dd dS )zd
        Soft delete objects from queryset (set their ``is_removed``
        field to True)
        TZ
is_removedN)r;   rj   r    r    r!   delete  s    z!SoftDeletableQuerySetMixin.deleteN)r#   r$   r%   __doc__rw   r    r    r    r!   ru      s   ru   c                   @   s   e Zd ZdS )SoftDeletableQuerySetNrm   r    r    r    r!   ry     s   ry   c                       s2   e Zd ZdZeZdd fdd
Zdd Z  ZS )SoftDeletableManagerMixinzf
    Manager that limits the queryset by default to show only not removed
    instances of model.
    F)_emit_deprecation_warningsc                   s   || _ t j|i | d S r'   )emit_deprecation_warningsr(   r)   )r   r{   r+   r,   r-   r    r!   r)     s    z"SoftDeletableManagerMixin.__init__c                 C   s\   | j r"d| jjj}t|t | j| jd}t	| drD| j
|d< | jf i |jddS )zA
        Return queryset limited to not removed entries.
        a  {0}.objects model manager will include soft-deleted objects in an upcoming release; please use {0}.available_objects to continue excluding soft-deleted objects. See https://django-model-utils.readthedocs.io/en/stable/models.html#softdeletablemodel for more information.r2   Zusing_hintshintsFrv   )r|   r8   r2   r.   r#   warningswarnDeprecationWarning_dbr@   r~   ri   rs   )r   Zwarning_messager,   r    r    r!   rk     s    

z&SoftDeletableManagerMixin.get_queryset)	r#   r$   r%   rx   ry   ri   r)   rk   r_   r    r    r-   r!   rz     s   rz   c                   @   s   e Zd ZdS )SoftDeletableManagerNrm   r    r    r    r!   r   2  s   r   c                   @   s   e Zd Zdd ZdddZdS )JoinQuerysetc                 C   s*   |  \}}dd |D }t|}|| S )Nc                 S   s$   g | ]}t |trd |n|qS )z'{}')r3   r4   r8   )rH   pr    r    r!   rJ   <  s   z1JoinQueryset.get_quoted_query.<locals>.<listcomp>)Zsql_with_paramsr   )r   r   paramsr    r    r!   get_quoted_query8  s    zJoinQueryset.get_quoted_queryNc                    s`  d|rfdd|j jjD }|r,|d nd}dj j }|pRt|j |d}|s`tdz
|jW n t	y   d|j
jY n0 |}}nd}j j }d |j}d	j t|d
}t }|| W d   n1 s0    Y  G  fdddtj}	t|	jj|j ddj jjdd}
|jj|
dd |S )a  
        Join one queryset together with another using a temporary table. If
        no queryset is used, it will use the current queryset and join that
        to itself.

        `Join` either uses the current queryset and effectively does a self-join to
        create a new limited queryset OR it uses a querset given by the user.

        The model of a given queryset needs to contain a valid foreign key to
        the current queryset to perform a join. A new queryset is then created.
        idc                    s"   g | ]}t |d d jkr|qS )Zrelated_modelN)r   r2   )rH   fkrj   r    r!   rJ   V  s   z%JoinQueryset.join.<locals>.<listcomp>r   Nz{}_setz(QuerySet is not related to current modelZ
temp_stuffz
            DROP TABLE IF EXISTS {table_name};
            DROP INDEX IF EXISTS {table_name}_id;
            CREATE TEMPORARY TABLE {table_name} AS {query};
            CREATE INDEX {table_name}_{fk_column} ON {table_name} ({fk_column});
        )
table_name	fk_columnr   c                       s4   e Zd ZejjejdZG  fdddZdS )z$JoinQueryset.join.<locals>.TempModel)Z	on_deleteZ	db_columnto_fieldc                       s   e Zd ZdZ ZdS )z)JoinQueryset.join.<locals>.TempModel.MetaFN)r#   r$   r%   Zmanagedrb   r    )
TABLE_NAMEr    r!   Meta  s   r   N)	r#   r$   r%   r   Z
ForeignKeyr2   Z
DO_NOTHINGZtemp_keyr   r    r   r   r   r   r    r!   	TempModel{  s   r   z
INNER JOINF)r   Zparent_aliasZtable_aliasZ	join_typeZ
join_fieldZnullable)Zreuse)r2   rU   fieldsr8   r#   lowerr   r7   columnAttributeErrorrO   onlyZobjectsallr   r   r4   r   cursorexecuter   ZModelr
   rb   Zget_initial_aliasZtempmodel_setrR   r9   )r   rG   r   Z	model_setr   r=   r   Zsqlr   r   connr    r   r!   r9   G  sL    





*zJoinQueryset.join)N)r#   r$   r%   r   r9   r    r    r    r!   r   6  s   r   c                   @   s   e Zd ZdZeZdd ZdS )JoinManagerMixinze
    Manager that adds a method join. This method allows you to join two
    querysets together.
    c                 C   s   | j | j| jdS )Nr}   )ri   r2   r   rj   r    r    r!   rk     s    zJoinManagerMixin.get_querysetN)r#   r$   r%   rx   r   ri   rk   r    r    r    r!   r     s   r   c                   @   s   e Zd ZdS )JoinManagerNrm   r    r    r    r!   r     s   r   )r   Zdjango.core.exceptionsr   Z	django.dbr   r   Zdjango.db.models.constantsr   Zdjango.db.models.fields.relatedr   r   Zdjango.db.models.queryr   r	   Z#django.db.models.sql.datastructuresr
   r   r&   r`   rh   Managerrl   rn   rt   ru   ry   rz   r   r   r   r   r    r    r    r!   <module>   s*    !]