
    Ƿi6Q                        d Z ddlZddlZ	 ddlZdZn# e$ r dZY nw xY w	 ddlZdZn# e$ r dZY nw xY wddlm	Z	 ddl
mZ ddlmZmZmZmZmZ ddlmZ dd	lmZ dd
lmZ ddlmZ  ee	dd          Z G d d          Z G d dee          Z G d dee          Z G d de          Z G d de          Z  G d de!          Z" G d d          Z# G d de#e          Z$dS )zo
Django Extensions additional model fields

Some fields might require additional dependencies to be installed.
    NTF)settings)ImproperlyConfigured)DateTimeField	CharField	SlugFieldQUniqueConstraint)
LOOKUP_SEP)slugify)get_random_string)	force_str$EXTENSIONS_MAX_UNIQUE_QUERY_ATTEMPTSd   c                   6    e Zd Zd Zed             Zd Zd ZdS )UniqueFieldMixinc                     t          t          | |          t                    s"t          d                    |                    d S )Nz#'{}' argument must be True or False)
isinstancegetattrbool
ValueErrorformat)selfattrnames     \/srv/django_bis/venv311/lib/python3.11/site-packages/django_extensions/db/fields/__init__.pycheck_is_boolzUniqueFieldMixin.check_is_bool%   sH    '$11488 	UBII(SSTTT	U 	U    c                 N      fd j                                         D             S )Nc                 t    g | ]4}|j         r|j        s|j        |j        ||j        k    r|j        nd f5S N)is_relation
one_to_onemany_to_onerelated_modelmodel).0f	model_clss     r   
<listcomp>z0UniqueFieldMixin._get_fields.<locals>.<listcomp>+   sf     
 
 
?@=
$%L
56]
GH
17i//T:
 
 
r   )_meta
get_fields)r'   s   `r   _get_fieldszUniqueFieldMixin._get_fields)   s<    
 
 
 
DMOD^D^D`D`
 
 
 	
r   c                     |                      |          D ](\  }}|r!||k    r|j                                        c S )|j                                        S r   )r+   _default_managerall)r   r'   
slug_fieldfieldr$   s        r   get_querysetzUniqueFieldMixin.get_queryset0   sf     ,,Y77 	4 	4LE5 4*,,-1133333)--///r   c                                           j        |          }j        r|                    j                  }i }j        j        D ]$} j        |v r|D ]}t          |d           ||<   %t                      }	t          j        dd           }
|
rGt          d |
          }|D ]3} j        |j
        v r# fd|j
        D             }|	t          di |z  }	4t          |          }|| j        <   |r |j	        |	fi |r)t          |          }|| j        <   | |j	        |	fi |)t           j        |           |S )N)pkconstraintsc                 ,    t          | t                    S r   )r   r	   )cs    r   <lambda>z.UniqueFieldMixin.find_unique.<locals>.<lambda>I   s    *Q(899 r   c                 J    i | ]}|j         k    |t          |d            S r   )attnamer   )r%   r0   model_instancer   s     r   
<dictcomp>z0UniqueFieldMixin.find_unique.<locals>.<dictcomp>M   s>     ! ! !! DL00 w~udCC000r    )r1   	__class__r3   excluder)   unique_togetherr9   r   r   filterfieldsnextsetattr)r   r:   r0   iteratorargsquerysetkwargsparamsparamqueryr4   unique_constraintsunique_constraint	conditionnews   ``             r   find_uniquezUniqueFieldMixin.find_unique6   s    $$^%=uEE 	>''>+<'==H $*: 	I 	IF|v%%# I IE$+NE4$H$HF5MM n2M4HH 	,!'99;" " &8 , ,!<#4#;;;! ! ! ! !%6%=! ! !I
 Q^^^^+E8nn"t| 	'99&99 	'x..C#&F4<   	'99&99 	' 	c222
r   N)__name__
__module____qualname__r   staticmethodr+   r1   rO   r<   r   r   r   r   #   s_        U U U 
 
 \
0 0 0$ $ $ $ $r   r   c                   f     e Zd ZdZ fdZd Zed             Zd Zd Z	d Z
d Zd	 Z fd
Z xZS )AutoSlugFielda  
    AutoSlugField

    By default, sets editable=False, blank=True.

    Required arguments:

    populate_from
        Specifies which field, list of fields, or model method
        the slug will be populated from.

        populate_from can traverse a ForeignKey relationship
        by using Django ORM syntax:
            populate_from = 'related_model__field'

    Optional arguments:

    separator
        Defines the used separator (default: '-')

    overwrite
        If set to True, overwrites the slug on every save (default: False)

    slugify_function
        Defines the function which will be used to "slugify" a content
        (default: :py:func:`~django.template.defaultfilters.slugify` )

    It is possible to provide custom "slugify" function with
    the ``slugify_function`` function in a model class.

    ``slugify_function`` function in a model class takes priority over
    ``slugify_function`` given as an argument to :py:class:`~AutoSlugField`.

    Example

    .. code-block:: python

        # models.py

        from django.db import models

        from django_extensions.db.fields import AutoSlugField


        class MyModel(models.Model):
            def slugify_function(self, content):
                return content.replace('_', '-').lower()

            title = models.CharField(max_length=42)
            slug = AutoSlugField(populate_from='title')

    Inspired by SmileyChris' Unique Slugify snippet:
    http://www.djangosnippets.org/snippets/690/
    c                 v   |                     dd           |                     dd           |                    dd           }|t          d          || _        t	          |          sJt          |t          t          f          s|f}t          d |D                       st          d|z            |                    d	t                    | _        |                    d
d          | _        |                    dd          | _        |                     d           |                    dd          | _        |                     d           |                    dd          | _        |                     d           |                    dt"                    | _         t'                      j        |i | d S )NblankTeditableFpopulate_fromz missing 'populate_from' argumentc              3   @   K   | ]}t          |t                    V  d S r   )r   str)r%   es     r   	<genexpr>z)AutoSlugField.__init__.<locals>.<genexpr>   s,      AAaz!S))AAAAAAr   zB'populate_from' must be str or list[str] or tuple[str], found `%s`slugify_function	separator-	overwriteoverwrite_on_addallow_duplicatesmax_unique_query_attempts)
setdefaultpopr   _populate_fromcallabler   listtupler.   	TypeErrorr   r^   r_   ra   r   rb   rc   MAX_UNIQUE_QUERY_ATTEMPTSrd   super__init__)r   rE   rG   rY   r=   s       r   rn   zAutoSlugField.__init__   s   '4(((*e,,,

?D99 ?@@@"/D&& 	vmdE];; 2!. 1AA=AAAAA v dgt tuuu &

+=w G GK55K77;''' &

+=t D D-... &

+=u E E-...)/4OQj)k)k&$)&)))))r   c                     dt          j        | j                  z  }t          j        d|z  | j        |          }t          j        d|d|dd|          S )a	  
        Clean up a slug by removing slug separator characters that occur at
        the beginning or end of a slug.

        If an alternate separator is used, it will also replace any instances
        of the default '-' separator with the new separator.
        z(?:-|%s)z%s+^z+|z+$ )reescaper_   sub)r   valuere_seps      r   _slug_stripzAutoSlugField._slug_strip   sV     bi777uv~t~u==vvffffff5r5AAAr   c                      | r ||           S dS Nrq   r<   )contentr^   s     r   slugify_funczAutoSlugField.slugify_func   s      	-##G,,,rr   c              #   R  K   |V  t          || j                  D ]q}|}| j        |}t          |          }| j        rBt          |          |z   | j        k    r'|d | j        |z
           }|                     |          }||}|V  rt          d|d| j        d          )Nzmax slug attempts for z exceeded ())rangerd   r_   lenslug_lenrw   RuntimeError)r   original_slugstartislugendend_lens          r   slug_generatorzAutoSlugField.slug_generator   s      ud<== 	 	A D NNAA.C#hhG} .TW!4t}!D!D4T]W445''--!T33'DJJJJl}}}VZVtVtVtuvvvr   c                    
 t           j                  }d}|r	 j        sd} j        r|rd}|r|S  j        }t          |t          t          f          s|f}j        	                     j                  }t          d j
                  
 
fd} j                            t          ||                    }d}|j         _         j        r|d  j                 }                     |          }|}	 j        rt%           j        |           |S                      |                     |	|                    S )NFTr^   c                 Z                                             |                     S )N)r^   )r{   get_slug_fields)lookup_valuer:   r   r^   s    r   r7   z+AutoSlugField.create_slug.<locals>.<lambda>   s3    d.?.?  >>- /@ /
 /
 r      )r   r9   ra   rb   rg   r   ri   rj   r)   	get_fieldr^   r_   joinmap
max_lengthr   rw   rc   rC   rO   r   )r   r:   addr   use_existing_slugrY   r/   slug_for_fieldr   r   r^   s   ``        @r   create_slugzAutoSlugField.create_slug   s   ~t|44! 	% 	% !%  	&S 	& % 	K +-$77 	.*-M#)33DLAA
">3EtG\]]
 
 
 
 
 
 ~""3~}#E#EFF #-= 	('D%%  	NDL$777KJ(;(;M5(Q(QS S 	Sr   c           
      B   t          |          rd ||          z  S |                    t                    }|}|D ]F}	 t          ||          }# t          $ r& t	          d                    ||||                    w xY wt          |          rd |            z  S |S )Nz%szbvalue {} in AutoSlugField's 'populate_from' argument {} returned an error - {} has no attribute {})rh   splitr
   r   AttributeErrorr   )r   r:   r   lookup_value_pathattrelems         r   r   zAutoSlugField.get_slug_fields   s    L!! 	7,,~6666(..z::% 	9 	9D9tT**! 9 9 9$xlD$8 89 9 99
 D>> 	!$$&&= s   A0B c                 L    t          |                     ||                    }|S r   )r   r   )r   r:   r   ru   s       r   pre_savezAutoSlugField.pre_save  s$    $**>3??@@r   c                     dS )Nr   r<   r   s    r   get_internal_typezAutoSlugField.get_internal_type      {r   c                     t                                                      \  }}}}| j        |d<   | j        dk    s
| j        |d<   | j        durd|d<   | j        durd|d<   ||||fS )NrY   r`   r_   FTra   rc   )rm   deconstructrg   r_   ra   rc   r   namepathrE   rG   r=   s        r   r   zAutoSlugField.deconstruct  s    #(77#6#6#8#8 dD&"&"5~$$"&.F;>&&"&F; --)-F%&T4''r   )rP   rQ   rR   __doc__rn   rw   rS   r{   r   r   r   r   r   r   __classcell__r=   s   @r   rU   rU   ]   s        5 5n* * * * *8
B 
B 
B   \
w w w+S +S +SZ  (    	( 	( 	( 	( 	( 	( 	( 	( 	(r   rU   c                   D     e Zd ZdZ fdZd Zd Zd Zd Z fdZ	 xZ
S )RandomCharFielda2  
    RandomCharField

    By default, sets editable=False, blank=True, unique=False.

    Required arguments:

    length
        Specifies the length of the field

    Optional arguments:

    unique
        If set to True, duplicate entries are not allowed (default: False)

    lowercase
        If set to True, lowercase the alpha characters (default: False)

    uppercase
        If set to True, uppercase the alpha characters (default: False)

    include_alpha
        If set to True, include alpha characters (default: True)

    include_digits
        If set to True, include digit characters (default: True)

    include_punctuation
        If set to True, include punctuation characters (default: False)

    keep_default
        If set to True, keeps the default initialization value (default: False)
    c                    |                     dd           |                     dd           |                    dd           | _        | j        t          d          | j        |d<   |                    dd          | _        |                     d           |                    d	d          | _        |                     d	           | j        r| j        rt          d
          |                    dd          | _        |                     d           |                    dd          | _        |                     d           |                    dd          | _	        |                    dd          | _
        |                     d           |                    dt                    | _        d|vrd|d<    t                      j        |i | d S )NrW   TrX   Flengthzmissing 'length' argumentr   	lowercase	uppercasez@the 'lowercase' and 'uppercase' arguments are mutually exclusiveinclude_digitsinclude_alphainclude_punctuationkeep_defaultrd   unique)re   rf   r   r   r   r   r   r   r   r   r   rl   rd   rm   rn   r   rE   rG   r=   s      r   rn   zRandomCharField.__init__G  s   '4(((*e,,,jj400;8999#{|K77;'''K77;'''> 	adn 	a_```$jj)94@@+,,,#ZZ>>?+++#)::.CU#K#K "JJ~u==0111)/4OQj)k)k& 6!!$F8$)&)))))r   c              #      K   t          | j                  D ],}d                    t          | j        |                    V  -t          d| j        z            )Nrq   z+max random character attempts exceeded (%s))r~   rd   r   r   r   r   )r   charsr   s      r   random_char_generatorz%RandomCharField.random_char_generatore  sa      t566 	A 	AA''+DK??@@@@@@H4Kiijjjr   c                 <    |j         j        D ]}| j        |v r dS dS )NTF)r)   r?   r9   )r   r:   rH   s      r   in_unique_togetherz"RandomCharField.in_unique_togetherj  s5    $*: 	 	F|v%%tt &ur   c                 l   |r| j         r.t          || j                  dk    rt          || j                  S d}| j        r=| j        r|t
          j        z  }n&| j        r|t
          j        z  }n|t
          j	        z  }| j
        r|t
          j        z  }| j        r|t
          j        z  }|                     |          }| j        s<|                     |          s't#          |          }t%          || j        |           |S |                     ||j                            | j                  |          S ry   )r   r   r9   r   r   stringascii_lowercaser   ascii_uppercaseascii_lettersr   digitsr   punctuationr   r   r   rB   rC   rO   r)   r   )r   r:   r   
populationrandom_charsrN   s         r   r   zRandomCharField.pre_savep  sG    	9t( 	9gndl.S.SWY.Y.Y>4<888
 	3~ 3f44

 3f44

f22
 	(&-'J# 	-&,,J11*=={ 	4#:#:>#J#J 	|$$CNDL#666J **4<88
 
 	
r   c                     dS )Nr   r<   r   s    r   internal_typezRandomCharField.internal_type  r   r   c                 X   t                                                      \  }}}}| j        |d<   |d= | j        du r
| j        |d<   | j        du r
| j        |d<   | j        du r
| j        |d<   | j        du r
| j        |d<   | j        du r
| j        |d	<   | j        du r
| j        |d
<   ||||fS )Nr   r   Tr   r   Fr   r   r   r   )	rm   r   r   r   r   r   r   r   r   r   s        r   r   zRandomCharField.deconstruct  s    #(77#6#6#8#8 dD&;x< >T!!"&.F;>T!!"&.F;&&&*&8F?#%'''+':F#$#t++,0,DF();$#{F8T4''r   )rP   rQ   rR   r   rn   r   r   r   r   r   r   r   s   @r   r   r   $  s           D* * * * *<k k k
  
 
 
>  ( ( ( ( ( ( ( ( (r   r   c                   .     e Zd ZdZd Zd Z fdZ xZS )CreationDateTimeFieldzc
    CreationDateTimeField

    By default, sets editable=False, blank=True, auto_now_add=True
    c                     |                     dd           |                     dd           |                     dd           t          j        | g|R i | d S )NrX   FrW   Tauto_now_addre   r   rn   r   rE   rG   s      r   rn   zCreationDateTimeField.__init__  sk    *e,,,'4(((.$///t5d555f55555r   c                     dS Nr   r<   r   s    r   r   z'CreationDateTimeField.get_internal_type      r   c                     t                                                      \  }}}}| j        durd|d<   | j        durd|d<   | j        durd|d<   ||||fS )NFTrX   rW   r   )rm   r   rX   rW   r   r   s        r   r   z!CreationDateTimeField.deconstruct  su    #(77#6#6#8#8 dD&=%%!%F::T!!#F7OE))%)F>"T4''r   )rP   rQ   rR   r   rn   r   r   r   r   s   @r   r   r     s`         6 6 6  ( ( ( ( ( ( ( ( (r   r   c                   8     e Zd ZdZd Zd Z fdZ fdZ xZS )ModificationDateTimeFieldz
    ModificationDateTimeField

    By default, sets editable=False, blank=True, auto_now=True

    Sets value to now every time the object is saved.
    c                 \    |                     dd           t          j        | g|R i | d S )Nauto_nowTr   r   s      r   rn   z"ModificationDateTimeField.__init__  s?    *d+++t5d555f55555r   c                     dS r   r<   r   s    r   r   z+ModificationDateTimeField.get_internal_type  r   r   c                 v    t                                                      \  }}}}| j        durd|d<   ||||fS )NFTr   )rm   r   r   r   s        r   r   z%ModificationDateTimeField.deconstruct  sG    #(77#6#6#8#8 dD&=%%!%F:T4''r   c                     t          |dd          st          || j                  S t                                          ||          S )Nupdate_modifiedT)r   r9   rm   r   )r   r:   r   r=   s      r   r   z"ModificationDateTimeField.pre_save  sD    ~'8$?? 	9>4<888ww444r   )	rP   rQ   rR   r   rn   r   r   r   r   r   s   @r   r   r     sy         6 6 6  ( ( ( ( (5 5 5 5 5 5 5 5 5r   r   c                       e Zd ZdS )UUIDVersionErrorN)rP   rQ   rR   r<   r   r   r   r     s        Dr   r   c                   P     e Zd ZdZdZ	 	 d fd	Zd Z fdZ fd	Z fd
Z	 xZ
S )UUIDFieldMixina  
    UUIDFieldMixin

    By default uses UUID version 4 (randomly generated UUID).

    The field support all uuid versions which are natively supported by the uuid python module, except version 2.
    For more information see: http://docs.python.org/lib/module-uuid.html
    $   NT   c	                 @   t           st          d          |
                    d| j                   |r"d| _        d|
d<   |
                    dd           || _        || _        || _        || _        || _	        |p|| _
         t                      j        |	d|i|
 d S )NzW'uuid' module is required for UUIDField. (Do you have Python 2.5 or higher installed ?)r   FTrW   rX   verbose_name)HAS_UUIDr   re   DEFAULT_MAX_LENGTHempty_strings_allowedautoversionnode	clock_seq	namespace	uuid_namerm   rn   )r   r   r   r   r   r   r   r   r   rE   rG   r=   s              r   rn   zUUIDFieldMixin.__init__  s      	B&  (A  B  B  B,(?@@@ 	1).D&"F7Oj%000		"""*dTDlDVDDDDDr   c                    | j         r| j         dk    rt          j                    S | j         dk    rt          j        | j        | j                  S | j         dk    rt          d          | j         dk    rt          j        | j        | j	                  S | j         dk    rt          j
        | j        | j	                  S t          d| j         z            )Nr      r    UUID version 2 is not supported.      UUID version %s is not valid.)r   uuiduuid4uuid1r   r   r   uuid3r   r   uuid5r   s    r   create_uuidzUUIDFieldMixin.create_uuid  s    | 	St|q00:<<\Q:di888\Q"#EFFF\Q:dndn===\Q:dndn==="#BT\#QRRRr   c                 T   t                                          ||          }| j        r=|r;|9t          |                                           }t          || j        |           |S | j        r9|s7t          |                                           }t          || j        |           |S r   )rm   r   r   r   r   rC   r9   )r   r:   r   ru   r=   s       r   r   zUUIDFieldMixin.pre_save  s      559 	= 	=d..0011ENDL%888Ly = =!$"2"2"4"455e<<<r   c                 H    | j         rd S  t                      j        di |S )Nr<   )r   rm   	formfield)r   rG   r=   s     r   r   zUUIDFieldMixin.formfield  s/    9 	4 uww **6***r   c                 v   t                                                      \  }}}}|                    dd           | j        k    r|d= | j        dur
| j        |d<   | j        dk    r
| j        |d<   | j        
| j        |d<   | j        
| j        |d<   | j        
| j        |d<   | j	        
| j
        |d	<   ||||fS )
Nr   Tr   r   r   r   r   r   r   )rm   r   getr   r   r   r   r   r   r   r   r   s        r   r   zUUIDFieldMixin.deconstruct#  s    #(77#6#6#8#8 dD&::lD))T-DDD|$9D  !YF6N<1 $F99 !YF6N>%"&.F;>%"&.F;>%"&)F;T4''r   )NNTr   NNNN)rP   rQ   rR   r   r   rn   r   r   r   r   r   r   s   @r   r   r     s          HIFJE E E E E E,S S S    + + + + +
( ( ( ( ( ( ( ( (r   r   c                   ,     e Zd ZdZdZ fdZd Z xZS )ShortUUIDFieldz
    ShortUUIDFied

    Generates concise (22 characters instead of 36), unambiguous, URL-safe UUIDs.

    Based on `shortuuid`: https://github.com/stochastic-technologies/shortuuid
       c                      t                      j        |i | t          st          d          |                    d| j                   d S )Nza'shortuuid' module is required for ShortUUIDField. (Do you have Python 2.5 or higher installed ?)r   )rm   rn   HAS_SHORT_UUIDr   re   r   r   s      r   rn   zShortUUIDField.__init__C  sb    $)&))) 	L&  (K  L  L  L,(?@@@@@r   c                 h   | j         r| j         dk    rt          j                    S | j         dk    rt          j                    S | j         dk    rt          d          | j         dk    rt          d          | j         dk    rt          j        | j                  S t          d	| j         z            )
Nr   r   r   r   r   z UUID version 3 is not supported.r   )r   r   )r   	shortuuidr   r   r   r   s    r   r   zShortUUIDField.create_uuidI  s    | 	St|q00>###\Q>###\Q"#EFFF\Q"#EFFF\Q>t~6666"#BT\#QRRRr   )rP   rQ   rR   r   r   rn   r   r   r   s   @r   r   r   8  se          A A A A AS S S S S S Sr   r   )%r   rr   r   r   r   ImportErrorr  r   django.confr   django.core.exceptionsr   django.db.modelsr   r   r   r   r	   django.db.models.constantsr
   django.template.defaultfiltersr   django.utils.cryptor   django.utils.encodingr   r   rl   r   rU   r   r   r   	Exceptionr   r   r   r<   r   r   <module>r     s    
			 KKKHH   HHHNN   NNN !           7 7 7 7 7 7 U U U U U U U U U U U U U U 1 1 1 1 1 1 2 2 2 2 2 2 1 1 1 1 1 1 + + + + + + $GH.TVYZZ 7 7 7 7 7 7 7 7tD( D( D( D( D($i D( D( D(N~( ~( ~( ~( ~(&	 ~( ~( ~(B( ( ( ( (M ( ( (65 5 5 5 5 5 5 5 58	 	 	 	 	y 	 	 	U( U( U( U( U( U( U( U(pS S S S S^Y S S S S Ss    ( 22