
    ]j8Q                        d Z ddlZddlZ	 ddlZdZ	 ddlZdZ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$y# e$ r dZY w xY w# e$ r dZY w xY w)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                   .    e Zd Zd Zed        Zd Zd Zy)UniqueFieldMixinc                 l    t        t        | |      t              st        dj	                  |            y )Nz#'{}' argument must be True or False)
isinstancegetattrbool
ValueErrorformat)selfattrnames     N/root/env/lib/python3.12/site-packages/django_extensions/db/fields/__init__.pycheck_is_boolzUniqueFieldMixin.check_is_bool%   s/    '$148BII(STT 9    c                     | j                   j                         D cg c]Q  }|j                  r$|j                  s|j                  r+|j
                  r||j                  | k7  r|j                  nd fS c}S c c}w N)_meta
get_fieldsis_relation
one_to_onemany_to_onerelated_modelmodel)	model_clsfs     r   _get_fieldszUniqueFieldMixin._get_fields)   sb     ENOOD^D^D`
?@==ALLQ]]q 177i/T:
 	
 
s   AA6c                     | j                  |      D ])  \  }}|s	||k(  s|j                  j                         c S  |j                  j                         S r   )r(   _default_managerall)r   r&   
slug_fieldfieldr%   s        r   get_querysetzUniqueFieldMixin.get_queryset0   sV     ,,Y7 	4LE5*,--1133	4 ))--//r   c           
      0   | j                  |j                  |      }|j                  r|j                  |j                        }i }|j                  j
                  D ](  }| j                  |v s|D ]  }t        ||d       ||<    * t               }	t        |j                  dd       }
|
rot        d |
      }|D ]]  }| j                  |j                  v s|j                  D ci c]  }|| j                  k7  r|t        ||d       ! }}|	t        di |z  }	_ t        |      }||| j                  <   |r |j                  |	fi |r1t        |      }||| j                  <   |s |j                  |	fi |r1t        || j                  |       |S c c}w )N)pkconstraintsc                 "    t        | t              S r   )r   r	   )cs    r   <lambda>z.UniqueFieldMixin.find_unique.<locals>.<lambda>I   s    *Q(89 r    )r.   	__class__r0   excluder   unique_togetherattnamer   r   filterfieldsnextsetattr)r   model_instancer-   iteratorargsquerysetkwargsparamsparamqueryr1   unique_constraintsunique_constraint	conditionnews                  r   find_uniquezUniqueFieldMixin.find_unique6   s    $$^%=%=uE''>+<+<'=H $**:: 	IF||v%# IE$+NE4$HF5MI	I n22M4H!'9;" &8 ,!<<#4#;#;; &7%=%=!! DLL0 w~udCC!I !
 Q^^+E, 8n"t||9&9x.C#&F4<<  9&9 	c2
!s   $$FN)__name__
__module____qualname__r   staticmethodr(   r.   rJ   r5   r   r   r   r   #   s&    U 
 
0$r   r   c                   `     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:
    https://www.djangosnippets.org/snippets/690/
    c                    |j                  dd       |j                  dd       |j                  dd       }|t        d      || _        t	        |      s9t        |t        t        f      s|f}t        d |D              st        d|z        |j                  d	t              | _        |j                  d
d      | _        |j                  dd      | _        | j                  d       |j                  dd      | _        | j                  d       |j                  dd      | _        | j                  d       |j                  dt"              | _        t'        | P  |i | y )NblankTeditableFpopulate_fromz missing 'populate_from' argumentc              3   <   K   | ]  }t        |t                y wr   )r   str).0es     r   	<genexpr>z)AutoSlugField.__init__.<locals>.<genexpr>   s     Aaz!S)As   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   rZ   r[   r]   r   r^   r_   MAX_UNIQUE_QUERY_ATTEMPTSr`   super__init__)r   r@   rB   rT   r6   s       r   rj   zAutoSlugField.__init__   s>   '4(*e,

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

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

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

+=u E-.)/4OQj)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   sM     bii77uv~t~~u=vvff5r5AAr   c                     | r ||       S yNrm   r5   )contentrZ   s     r   slugify_funczAutoSlugField.slugify_func   s    #G,,r   c              #   b  K   | t        || j                        D ]s  }|}| j                  |}t        |      }| j                  r>t        |      |z   | j                  kD  r#|d | j                  |z
   }| j                  |      }||}| u t        d|d| j                  d      w)Nzmax slug attempts for z exceeded ())ranger`   r[   lenslug_lenrs   RuntimeError)r   original_slugstartislugendend_lens          r   slug_generatorzAutoSlugField.slug_generator   s     ud<<= 	A D NNA.C#hG}}TW!4t}}!D4T]]W45''-!3'DJ	 }VZVtVtuvvs   B-B/c                    
 t         j                        }d}|r j                  sd} j                  r|rd}|r|S  j                  }t        |t        t        f      s|f}j                  j                   j                        }t        d j                        
 
fd} j                  j                  t        ||            }d}|j                   _         j                  r|d  j                   } j!                  |      }|}	 j"                  rt%         j                  |       |S  j'                  | j)                  |	|            S )NFTrZ   c                 J    j                  j                  |             S )N)rZ   )rw   get_slug_fields)lookup_valuer>   r   rZ   s    r   r4   z+AutoSlugField.create_slug.<locals>.<lambda>   s+    d.?.?  >- /@ /
 r      )r   r9   r]   r^   rc   r   re   rf   r   	get_fieldrZ   r[   joinmap
max_lengthr|   rs   r_   r=   rJ   r   )r   r>   addr   use_existing_slugrT   r,   slug_for_fieldr   r~   rZ   s   ``        @r   create_slugzAutoSlugField.create_slug   sA   ~t||4! !%  S %K ++-$7*-M#))33DLLA
">3EtG\G\]
 ~~""3~}#EF #--=='D%  NDLL$7KJ(;(;M5(QS 	Sr   c           
         t        |      rd ||      z  S |j                  t              }|}|D ]  }	 t        ||      } t        |      r
d |       z  S |S # t        $ r t	        dj                  ||||            w xY w)Nz%szbvalue {} in AutoSlugField's 'populate_from' argument {} returned an error - {} has no attribute {})rd   splitr
   r   AttributeErrorr   )r   r>   r   lookup_value_pathattrelems         r   r   zAutoSlugField.get_slug_fields   s    L!,~666(..z:% 	9D9tT*	9 D>$&=  " 9$xlD$89 99s   A'B c                 <    t        | j                  ||            }|S r   )r   r   )r   r>   r   rq   s       r   pre_savezAutoSlugField.pre_save  s    $**>3?@r   c                      y)Nr   r5   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 )NrT   r\   r[   FTr]   r_   )ri   deconstructrc   r[   r]   r_   r   namepathr@   rB   r6   s        r   r   zAutoSlugField.deconstruct  s    #(7#6#8 dD&"&"5"5~~$"&..F;>>&"&F;  -)-F%&T4''r   )rK   rL   rM   __doc__rj   rs   rN   rw   r   r   r   r   r   r   __classcell__r6   s   @r   rP   rP   ]   sN    5n*8
B  
w+SZ(	( 	(r   rP   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                 2   |j                  dd       |j                  dd       |j                  dd       | _        | j                  t        d      | j                  |d<   |j                  dd      | _        | j                  d       |j                  d	d      | _        | j                  d	       | j                  r| j                  rt        d
      |j                  dd      | _        | j                  d       |j                  dd      | _        | j                  d       |j                  dd      | _	        |j                  dd      | _
        | j                  d       |j                  dt              | _        d|vrd|d<   t        | 8  |i | y )NrR   TrS   Flengthzmissing 'length' argumentr   	lowercase	uppercasez@the 'lowercase' and 'uppercase' arguments are mutually exclusiveinclude_digitsinclude_alphainclude_punctuationkeep_defaultr`   unique)ra   rb   r   r   r   r   r   r   r   r   r   rh   r`   ri   rj   r   r@   rB   r6   s      r   rj   zRandomCharField.__init__G  sg   '4(*e,jj40;;899#{{|K7;'K7;'>>dnn_``$jj)94@+,#ZZ>?+#)::.CU#K "JJ~u=01)/4OQj)k& 6!$F8$)&)r   c              #      K   t        | j                        D ])  }dj                  t        | j                  |             + t        d| j                  z        w)Nrm   z+max random character attempts exceeded (%s))rz   r`   r   r   r   r}   )r   charsr   s      r   random_char_generatorz%RandomCharField.random_char_generatore  sT     t556 	AA''+DKK?@@	AH4KiKiijjs   AAc                 Z    |j                   j                  D ]  }| j                  |v s y y)NTF)r   r8   r9   )r   r>   rC   s      r   in_unique_togetherz"RandomCharField.in_unique_togetherj  s1    $**:: 	F||v%	 r   c                    |r| j                   r/t        || j                        dk7  rt        || j                        S d}| j                  rS| j                  r|t
        j                  z  }n3| j                  r|t
        j                  z  }n|t
        j                  z  }| j                  r|t
        j                  z  }| j                  r|t
        j                  z  }| j                  |      }| j                  s5| j!                  |      s$t#        |      }t%        || j                  |       |S | j'                  ||j(                  j+                  | j                        |      S ru   )r   r   r9   r   r   stringascii_lowercaser   ascii_uppercaseascii_lettersr   digitsr   punctuationr   r   r   r<   r=   rJ   r   r   )r   r>   r   
populationrandom_charsrI   s         r   r   zRandomCharField.pre_savep  s!   t((gndll.SWY.Y>4<<88
~~f444
f444
f222
&--'J##&,,,J11*={{4#:#:>#J|$CNDLL#6J  **4<<8
 	
r   c                      y)Nr   r5   r   s    r   internal_typezRandomCharField.internal_type  r   r   c                    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   )	ri   r   r   r   r   r   r   r   r   r   s        r   r   zRandomCharField.deconstruct  s    #(7#6#8 dD&;;x< >>T!"&..F;>>T!"&..F;&&*&8&8F?#%''+':':F#$##t+,0,D,DF();;$#{{F8T4''r   )rK   rL   rM   r   rj   r   r   r   r   r   r   r   s   @r   r   r   $  s-     D*<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                     |j                  dd       |j                  dd       |j                  dd       t        j                  | g|i | y )NrS   FrR   Tauto_now_addra   r   rj   r   r@   rB   s      r   rj   zCreationDateTimeField.__init__  sJ    *e,'4(.$/t5d5f5r   c                      yNr   r5   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 )NFTrS   rR   r   )ri   r   rS   rR   r   r   s        r   r   z!CreationDateTimeField.deconstruct  sk    #(7#6#8 dD&==%!%F:::T!#F7OE)%)F>"T4''r   )rK   rL   rM   r   rj   r   r   r   r   s   @r   r   r     s    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                 Z    |j                  dd       t        j                  | g|i | y )Nauto_nowTr   r   s      r   rj   z"ModificationDateTimeField.__init__  s*    *d+t5d5f5r   c                      yr   r5   r   s    r   r   z+ModificationDateTimeField.get_internal_type  r   r   c                 \    t         |          \  }}}}| j                  durd|d<   ||||fS )NFTr   )ri   r   r   r   s        r   r   z%ModificationDateTimeField.deconstruct  s>    #(7#6#8 dD&==%!%F:T4''r   c                 j    t        |dd      st        || j                        S t        |   ||      S )Nupdate_modifiedT)r   r9   ri   r   )r   r>   r   r6   s      r   r   z"ModificationDateTimeField.pre_save  s3    ~'8$?>4<<88w44r   )	rK   rL   rM   r   rj   r   r   r   r   r   s   @r   r   r     s!    6(5 5r   r   c                       e Zd Zy)UUIDVersionErrorN)rK   rL   rM   r5   r   r   r   r     s    r   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: https://docs.python.org/lib/module-uuid.html
    $   c	                    t         st        d      |
j                  d| j                         |rd| _        d|
d<   |
j                  dd       || _        || _        || _        || _        || _	        |xs || _
        t        | 0  |	d|i|
 y )NzW'uuid' module is required for UUIDField. (Do you have Python 2.5 or higher installed ?)r   FTrR   rS   verbose_name)HAS_UUIDr   ra   DEFAULT_MAX_LENGTHempty_strings_allowedautoversionnode	clock_seq	namespace	uuid_nameri   rj   )r   r   r   r   r   r   r   r   r   r@   rB   r6   s              r   rj   zUUIDFieldMixin.__init__  s     &  (A  B  B,(?(?@).D&"F7Oj%0		"""*dTDlDV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        )N      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    ||t||q0::<\\Q::dii88\\Q"#EFF\\Q::dnndnn==\\Q::dnndnn=="#BT\\#QRRr   c                 (   t         |   ||      }| j                  r6|r4|2t        | j	                               }t        || j                  |       |S | j                  r2|s0t        | j	                               }t        || j                  |       |S r   )ri   r   r   r   r   r=   r9   )r   r>   r   rq   r6   s       r   r   zUUIDFieldMixin.pre_save  sz     599d..01ENDLL%8Lyy!$"2"2"45e<r   c                 <    | j                   ry t        |   di |S )Nr5   )r   ri   	formfield)r   rB   r6   s     r   r   zUUIDFieldMixin.formfield  s     99w *6**r   c                    t         |          \  }}}}|j                  dd       | j                  k(  r|d= | j                  dur| j                  |d<   | j
                  dk7  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   )ri   r   getr   r   r   r   r   r   r   r   r   s        r   r   zUUIDFieldMixin.deconstruct#  s    #(7#6#8 dD&::lD)T-D-DD|$99D !YYF6N<<1 $F999 !YYF6N>>%"&..F;>>%"&..F;>>%"&))F;T4''r   )NNTr   NNNN)rK   rL   rM   r   r   rj   r   r   r   r   r   r   s   @r   r   r     s6     HIFJE,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        |   |i | t        st        d      |j	                  d| j
                         y )Nza'shortuuid' module is required for ShortUUIDField. (Do you have Python 2.5 or higher installed ?)r   )ri   rj   HAS_SHORT_UUIDr   ra   r   r   s      r   rj   zShortUUIDField.__init__C  sC    $)&)&  (K  L  L,(?(?@r   c                    | 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    ||t||q0>>##\\Q>>##\\Q"#EFF\\Q"#EFF\\Q>>t~~66"#BT\\#QRRr   )rK   rL   rM   r   r   rj   r   r   r   s   @r   r   r   8  s     ASr   r   )%r   rn   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   rh   r   rP   r   r   r   	Exceptionr   r   r   r5   r   r   <module>r     s    
 HN ! 7 U U 1 2 1 + $H.TVYZ 7 7tD($i D(N~(&	 ~(B(M (65 5 58	y 	U( U(pS^Y SU  H  Ns"   B/ B< /B98B9<CC