o
    Ti5                     @   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                   @      e Zd Zdd ZdS )InheritanceIterablec           	      c   s    | j }t|}t|ddr`t|jj }t|jt	dd}|D ]=}d }|D ]}|
||}|r2 nq&|s7|}t|ddrL|jD ]}t||t|| q@|D ]}t||t|| qN|V  q d S |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!   T/var/www/html/evchargy.com/venv/lib/python3.10/site-packages/model_utils/managers.py__iter__   s.   
zInheritanceIterable.__iter__N)__name__
__module____qualname__r#   r!   r!   r!   r"   r          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|}n0g }|D ])}|| ju rqt|tfs(| j||d}||v r2|| qtd|d||}|rG| j	| }n| }||_
|S )Nlevelsz3{!r} is not in the discovered subclasses, tried: {}z, )_get_subclasses_recursemodel
isinstancestr_get_ancestors_pathappend
ValueErrorformatjoinZselect_relatedr   )r   r   r2   Zcalculated_subclassesZverified_subclassessubclassnew_qsr!   r!   r"   select_subclasses.   s6   

z*InheritanceQuerySetMixin.select_subclassesc                    sH   i }dD ]}t | |rt| |||< qt jdi |}|j| |S )Nr   r   r!   )hasattrr   r*   _chain__dict__update)r   r.   rC   nameZchainedr/   r!   r"   rA   R   s   
zInheritanceQuerySetMixin._chainNFc                    s4   t   }dD ]}t| |rt||t| | q|S )Nr?   )r*   _cloner@   r   r   )r   klasssetupr.   qsrD   r/   r!   r"   rE   \   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>e   s    z5InheritanceQuerySetMixin.annotate.<locals>.<listcomp>)r*   annotatelistr   r   )r   r-   r.   Zqsetr/   r!   r"   rL   c   s   z!InheritanceQuerySetMixin.annotatec                    s   dd  j  D } fdd|D }g }|r|d8 }|D ]&}|s%|du r<| 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!   )r5   r   )rI   fr!   r!   r"   rK   n   s    zDInheritanceQuerySetMixin._get_subclasses_recurse.<locals>.<listcomp>c                    s<   g | ]}t |jtrt|jj r |jjur|jr|qS r!   )r5   fieldr   
issubclassr4   parent_link)rI   relr4   r!   r"   rK   r   s    
   Nr1   )_metaZ
get_fieldsr3   rO   r4   r8   get_accessor_namer   )r   r4   r2   Zrelated_objectsZrelsr   rR   r<   r!   rS   r"   r3   h   s&   

z0InheritanceQuerySetMixin._get_subclasses_recursec                 C   s   t || jst|d| jg }|j| j}|r|d8 }|durE|j}|d|  |s4|du r?|j}|j| j}nd}|dus#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 is not a subclass of rT   Nr   )
rP   r4   r9   rU   Zget_ancestor_linkZremote_fieldinsertrV   r   r;   )r   r4   r2   ZancestryrQ   relatedZparent_modelr!   r!   r"   r7      s&   
	z,InheritanceQuerySetMixin._get_ancestors_pathc                 C   sL   | t\}}}zt||}W n
 ty   Y d S w |r$| ||}|S |S r)   )	partitionr   r   r   r   )r   r   r   rR   _nodechildr!   r!   r"   r      s   z-InheritanceQuerySetMixin._get_sub_obj_recursec                 O      |   j|i |S r)   )r>   getr,   r!   r!   r"   get_subclass      z%InheritanceQuerySetMixin.get_subclass)NFr)   )r$   r%   r&   r+   r>   rA   rE   rL   r3   r7   r   r_   __classcell__r!   r!   r/   r"   r(   )   s    $


r(   c                   @   r   )InheritanceQuerySetc              	      sV   g }|D ] | 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)r:   rU   db_tableZattname)rI   rO   rS   r!   r"   rK      s    z3InheritanceQuerySet.instance_of.<locals>.<listcomp>)z OR )where)r8   r;   rU   parentsvaluesr>   r   )r   r   Zwhere_queriesr!   rS   r"   instance_of   s   
zInheritanceQuerySet.instance_ofN)r$   r%   r&   ri   r!   r!   r!   r"   rb      r'   rb   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_classr4   r   r!   r!   r"   get_queryset   s   z$InheritanceManagerMixin.get_querysetc                 G      |   j| S r)   )rm   r>   )r   r   r!   r!   r"   r>         z)InheritanceManagerMixin.select_subclassesc                 O   r]   r)   )rm   r_   r,   r!   r!   r"   r_      r`   z$InheritanceManagerMixin.get_subclassc                 G   rn   r)   )rm   ri   )r   r   r!   r!   r"   ri      ro   z#InheritanceManagerMixin.instance_ofN)	r$   r%   r&   rb   rk   rm   r>   r_   ri   r!   r!   r!   r"   rj      s    rj   c                   @      e Zd ZdS )InheritanceManagerNr$   r%   r&   r!   r!   r!   r"   rq          rq   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di || _ d | _t   d S )Nr   r!   )_qr   Q	_order_byr*   r+   r,   r/   r!   r"   r+      s
   zQueryManagerMixin.__init__c                 G   s
   || _ | S r)   )rw   )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*   rm   filterru   rw   rx   )r   rH   r/   r!   r"   rm      s   
zQueryManagerMixin.get_queryset)r$   r%   r&   r+   rx   rm   ra   r!   r!   r/   r"   rt      s    rt   c                   @   rp   )QueryManagerNrr   r!   r!   r!   r"   rz      rs   rz   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)rC   rl   r!   r!   r"   delete   s   z!SoftDeletableQuerySetMixin.deleteN)r$   r%   r&   __doc__r}   r!   r!   r!   r"   r{      s    r{   c                   @   rp   )SoftDeletableQuerySetNrr   r!   r!   r!   r"   r     rs   r   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r"| j
|d< | jd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.r4   using_hintshintsFr|   Nr!   )r   r:   r4   r0   r$   warningswarnDeprecationWarning_dbr@   r   rk   ry   )r   Zwarning_messager.   r!   r!   r"   rm     s   

z&SoftDeletableManagerMixin.get_queryset)	r$   r%   r&   r~   r   rk   r+   rm   ra   r!   r!   r/   r"   r     s
    r   c                   @   rp   )SoftDeletableManagerNrr   r!   r!   r!   r"   r   ,  rs   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 | d n|qS )')r5   r6   )rI   pr!   r!   r"   rK   6  s    z1JoinQueryset.get_quoted_query.<locals>.<listcomp>)Zsql_with_paramsr   )r   r   paramsr!   r!   r"   get_quoted_query2  s   zJoinQueryset.get_quoted_queryNc                    s^  d|rMfdd|j jjD }|r|d nd}j j  d}|p)t|j |d}|s0tdz|jW n tyD   d|j	jY nw |
}}nd
}j j }d |j}d	j t|d
}t }|| W d   n1 sw   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 queryset 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   r4   )rI   fkrl   r!   r"   rK   P  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managedrd   r!   )
TABLE_NAMEr!   r"   Meta}  s    r   N)	r$   r%   r&   r   Z
ForeignKeyr4   Z
DO_NOTHINGZtemp_keyr   r!   r   r   r   r   r!   r"   	TempModelu  s    r   z
INNER JOINF)r   Zparent_aliasZtable_aliasZ	join_typeZ
join_fieldZnullable)Zreuse)r4   rU   fieldsr$   lowerr   r9   columnAttributeErrorrO   onlyobjectsallr   r   r:   r6   r   cursorexecuter   ZModelr
   rd   Zget_initial_aliasZtempmodel_setrR   r;   )r   rH   r   Z	model_setr   r=   r   sqlr   r   connr!   r   r"   r;   A  sP   




zJoinQueryset.joinr)   )r$   r%   r&   r   r;   r!   r!   r!   r"   r   0  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   )rk   r4   r   rl   r!   r!   r"   rm     s   zJoinManagerMixin.get_querysetN)r$   r%   r&   r~   r   rk   rm   r!   r!   r!   r"   r     s    r   c                   @   rp   )JoinManagerNrr   r!   r!   r!   r"   r     rs   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(   rb   rj   Managerrq   rt   rz   r{   r   r   r   r   r   r   r!   r!   r!   r"   <module>   s,     	!]