a
    8¤Xh8Q  ã                   @   sZ  d Z ddlZddlZzddlZdZW n ey:   dZY n0 zddlZdZW n eyb   dZY n0 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„ dƒZG dd„ deeƒZG dd„ deeƒZG dd„ deƒZG dd„ deƒZ G dd„ de!ƒZ"G dd„ dƒZ#G d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_strZ$EXTENSIONS_MAX_UNIQUE_QUERY_ATTEMPTSéd   c                   @   s0   e Zd Zdd„ Zedd„ ƒZdd„ Zdd„ Zd	S )
ÚUniqueFieldMixinc                 C   s"   t t| |ƒtƒstd |¡ƒ‚d S )Nz#'{}' argument must be True or False)Ú
isinstanceÚgetattrÚboolÚ
ValueErrorÚformat)ÚselfÚattrname© r   úi/var/www/viveiro_mudafortebrasil/venv/lib/python3.9/site-packages/django_extensions/db/fields/__init__.pyÚcheck_is_bool%   s    zUniqueFieldMixin.check_is_boolc                    s   ‡ fdd„ˆ j  ¡ D ƒS )Nc                    s<   g | ]4}|j r |js |jr|jr||jˆ kr2|jnd f‘qS ©N)Zis_relationZ
one_to_oneZmany_to_oneZrelated_modelÚmodel)Ú.0Úf©Ú	model_clsr   r   Ú
<listcomp>+   s   ÿz0UniqueFieldMixin._get_fields.<locals>.<listcomp>)Ú_metaZ
get_fieldsr   r   r   r   Ú_get_fields)   s    
ÿzUniqueFieldMixin._get_fieldsc                 C   s8   |   |¡D ]"\}}|r
||kr
|j ¡   S q
|j ¡ S r   )r!   Z_default_managerÚall)r   r   Ú
slug_fieldÚfieldr   r   r   r   Úget_queryset0   s    zUniqueFieldMixin.get_querysetc                    s
  ˆ  ˆ j|¡}ˆ jr"|jˆ jd}i }ˆ jjD ](}ˆj|v r.|D ]}tˆ |d ƒ||< q@q.tƒ }	tˆ jdd ƒ}
|
r¼t	dd„ |
ƒ}|D ]8}ˆj|j
v r‚‡ ‡fdd„|j
D ƒ}|	tf i |¤ŽM }	q‚t|ƒ}||ˆj< |rä|j	|	fi |¤Žrøt|ƒ}||ˆj< qÎtˆ ˆj|ƒ |S )N)ÚpkÚconstraintsc                 S   s
   t | tƒS r   )r   r   )Úcr   r   r   Ú<lambda>I   ó    z.UniqueFieldMixin.find_unique.<locals>.<lambda>c                    s$   i | ]}|ˆj kr|tˆ |d ƒ“qS r   )Úattnamer   )r   r$   ©Úmodel_instancer   r   r   Ú
<dictcomp>M   s   
þz0UniqueFieldMixin.find_unique.<locals>.<dictcomp>)r%   Ú	__class__r&   Úexcluder    Úunique_togetherr+   r   r   ÚfilterÚfieldsÚnextÚsetattr)r   r-   r$   ÚiteratorÚargsZquerysetÚkwargsÚparamsÚparamÚqueryr'   Zunique_constraintsZunique_constraintÚ	conditionÚnewr   r,   r   Úfind_unique6   s6    
ÿþ
zUniqueFieldMixin.find_uniqueN)Ú__name__Ú
__module__Ú__qualname__r   Ústaticmethodr!   r%   r>   r   r   r   r   r   #   s
   
r   c                       sh   e Zd ZdZ‡ fdd„Zdd„ Zedd„ ƒZdd	„ Zd
d„ Z	dd„ Z
dd„ Zdd„ Z‡ fdd„Z‡  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                    sþ   |  dd¡ |  dd¡ | dd ¡}|d u r6tdƒ‚n|| _t|ƒsvt|ttfƒsX|f}tdd„ |D ƒƒsvt	d	| ƒ‚| 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                 s   s   | ]}t |tƒV  qd S r   )r   Ústr)r   Úer   r   r   Ú	<genexpr>£   r*   z)AutoSlugField.__init__.<locals>.<genexpr>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
   rJ   rK   rM   r   rN   rO   ÚMAX_UNIQUE_QUERY_ATTEMPTSrP   ÚsuperÚ__init__)r   r7   r8   rF   ©r/   r   r   rZ   •   s*    



zAutoSlugField.__init__c                 C   s:   dt  | j¡ }t  d| | j|¡}t  d||f 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	^%s+|%s+$Ú )ÚreÚescaperK   Úsub)r   ÚvalueZre_sepr   r   r   Ú_slug_strip±   s    zAutoSlugField._slug_stripc                 C   s   | r|| ƒS dS ©Nr\   r   )ÚcontentrJ   r   r   r   Úslugify_func½   s    zAutoSlugField.slugify_funcc                 c   sŽ   |V  t || jƒD ]d}|}d| j|f }t|ƒ}| jrdt|ƒ| | jkrd|d | j| … }|  |¡}d||f }|V  qtd|| jf ƒ‚d S )Nz%s%sz&max slug attempts for %s exceeded (%s))ÚrangerP   rK   ÚlenÚslug_lenra   ÚRuntimeError)r   Úoriginal_slugÚstartÚiÚslugÚendZend_lenr   r   r   Úslug_generatorÃ   s    
zAutoSlugField.slug_generatorc           
         sè   t ˆ ˆjƒ}d}|rˆjsd}ˆjr,|r,d}|r4|S ˆj}t|ttfƒsN|f}ˆ j 	ˆj¡}t ˆ dˆj
ƒ‰‡ ‡‡fdd„}ˆj t||ƒ¡}d}|jˆ_ˆjr¬|d ˆj… }ˆ |¡}|}	ˆjrÒtˆ ˆj|ƒ |S ˆ ˆ |ˆ |	|¡¡S )NFTrJ   c                    s   ˆj ˆ ˆ | ¡ˆdS )N)rJ   )rd   Úget_slug_fields)Úlookup_value©r-   r   rJ   r   r   r)   ç   s   
þz+AutoSlugField.create_slug.<locals>.<lambda>é   )r   r+   rM   rN   rS   r   rU   rV   r    Ú	get_fieldrJ   rK   ÚjoinÚmapÚ
max_lengthrg   ra   rO   r5   r>   rn   )
r   r-   Úaddrl   Zuse_existing_slugrF   r#   Zslug_for_fieldrj   ri   r   rq   r   Úcreate_slugÐ   s6    


ÿzAutoSlugField.create_slugc                 C   sx   t |ƒrd||ƒ S | t¡}|}|D ]:}zt||ƒ}W q& ty^   td ||||¡ƒ‚Y q&0 q&t |ƒrtd|ƒ  S |S )Nz%szbvalue {} in AutoSlugField's 'populate_from' argument {} returned an error - {} has no attribute {})rT   Úsplitr	   r   ÚAttributeErrorr   )r   r-   rp   Zlookup_value_pathÚattrÚelemr   r   r   ro   ý   s     
ÿÿ
zAutoSlugField.get_slug_fieldsc                 C   s   t |  ||¡ƒ}|S r   )r   rx   ©r   r-   rw   r`   r   r   r   Úpre_save  s    zAutoSlugField.pre_savec                 C   s   dS )Nr   r   ©r   r   r   r   Úget_internal_type  s    zAutoSlugField.get_internal_typec                    s`   t ƒ  ¡ \}}}}| j|d< | jdks0| j|d< | jdurBd|d< | jdurTd|d< ||||fS )NrF   rL   rK   FTrM   rO   )rY   ÚdeconstructrS   rK   rM   rO   ©r   ÚnameÚpathr7   r8   r[   r   r   r     s    




zAutoSlugField.deconstruct)r?   r@   rA   Ú__doc__rZ   ra   rB   rd   rn   rx   ro   r~   r€   r   Ú__classcell__r   r   r[   r   rC   ]   s   7
-rC   c                       sL   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Zdd	„ Zd
d„ Z‡ fdd„Z	‡  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                    s  |  dd¡ |  dd¡ | dd ¡| _| jd u r8t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 )NrD   TrE   FÚlengthzmissing 'length' argumentrv   Ú	lowercaseÚ	uppercasez@the 'lowercase' and 'uppercase' arguments are mutually exclusiveÚinclude_digitsÚinclude_alphaÚinclude_punctuationÚkeep_defaultrP   Úunique)rQ   rR   rˆ   r   r‰   r   rŠ   r‹   rŒ   r   rŽ   rX   rP   rY   rZ   ©r   r7   r8   r[   r   r   rZ   G  s.    






zRandomCharField.__init__c                 c   s6   t | jƒD ]}d t| j|ƒ¡V  q
td| j ƒ‚d S )Nr\   z+max random character attempts exceeded (%s))re   rP   rt   r   rˆ   rh   )r   Úcharsrk   r   r   r   Úrandom_char_generatore  s    z%RandomCharField.random_char_generatorc                 C   s"   |j jD ]}| j|v r dS qdS )NTF)r    r1   r+   )r   r-   r9   r   r   r   Úin_unique_togetherj  s    
z"RandomCharField.in_unique_togetherc                 C   sÊ   |r
| j r&t|| jƒdkr&t|| jƒS d}| jr^| jrB|tj7 }n| jrT|tj7 }n
|tj	7 }| j
rn|tj7 }| jr~|tj7 }|  |¡}| js²|  |¡s²t|ƒ}t|| j|ƒ |S |  ||j | j¡|¡S rb   )rŽ   r   r+   rŒ   r‰   ÚstringÚascii_lowercaserŠ   Úascii_uppercaseÚascii_lettersr‹   Údigitsr   Úpunctuationr’   r   r“   r4   r5   r>   r    rs   )r   r-   rw   Ú
populationZrandom_charsr=   r   r   r   r~   p  s.    



ýzRandomCharField.pre_savec                 C   s   dS )Nr   r   r   r   r   r   Úinternal_type  s    zRandomCharField.internal_typec                    s¦   t ƒ  ¡ \}}}}| j|d< |d= | jdu r6| j|d< | jdu rJ| j|d< | jdu r^| j|d< | jdu rr| j|d< | jdu r†| j|d	< | jdu rš| j|d
< ||||fS )Nrˆ   rv   Tr‰   rŠ   FrŒ   r‹   r   r   )	rY   r   rˆ   r‰   rŠ   rŒ   r‹   r   r   r‚   r[   r   r   r   ’  s     












zRandomCharField.deconstruct)r?   r@   rA   r…   rZ   r’   r“   r~   r›   r   r†   r   r   r[   r   r‡   $  s   "r‡   c                       s0   e Zd ZdZdd„ Zdd„ Z‡ fdd„Z‡  ZS )ÚCreationDateTimeFieldzc
    CreationDateTimeField

    By default, sets editable=False, blank=True, auto_now_add=True
    c                 O   s@   |  dd¡ |  dd¡ |  dd¡ tj| g|¢R i |¤Ž d S )NrE   FrD   TÚauto_now_add©rQ   r   rZ   r   r   r   r   rZ   ¬  s    zCreationDateTimeField.__init__c                 C   s   dS ©Nr   r   r   r   r   r   r€   ²  s    z'CreationDateTimeField.get_internal_typec                    sT   t ƒ  ¡ \}}}}| jdur$d|d< | jdur6d|d< | jdurHd|d< ||||fS )NFTrE   rD   r   )rY   r   rE   rD   r   r‚   r[   r   r   r   µ  s    


z!CreationDateTimeField.deconstruct)r?   r@   rA   r…   rZ   r€   r   r†   r   r   r[   r   rœ   ¥  s   rœ   c                       s<   e Zd ZdZdd„ Zdd„ Z‡ fdd„Z‡ fdd	„Z‡  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                 O   s(   |  dd¡ tj| g|¢R i |¤Ž d S )NÚauto_nowTrž   r   r   r   r   rZ   É  s    z"ModificationDateTimeField.__init__c                 C   s   dS rŸ   r   r   r   r   r   r€   Í  s    z+ModificationDateTimeField.get_internal_typec                    s0   t ƒ  ¡ \}}}}| jdur$d|d< ||||fS )NFTr¡   )rY   r   r¡   r‚   r[   r   r   r   Ð  s    
z%ModificationDateTimeField.deconstructc                    s&   t |ddƒst || jƒS tƒ  ||¡S )NZupdate_modifiedT)r   r+   rY   r~   )r   r-   rw   r[   r   r   r~   Ö  s    z"ModificationDateTimeField.pre_save)	r?   r@   rA   r…   rZ   r€   r   r~   r†   r   r   r[   r   r    À  s
   r    c                   @   s   e Zd ZdS )ÚUUIDVersionErrorN)r?   r@   rA   r   r   r   r   r¢   Ü  s   r¢   c                       sR   e Zd ZdZdZd‡ fdd„	Zdd	„ Z‡ fd
d„Z‡ fdd„Z‡ fdd„Z	‡  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
    é$   NTé   c	                    sz   t stdƒ‚|
 d| j¡ |r8d| _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 ?)rv   FTrD   rE   Úverbose_name)ÚHAS_UUIDr   rQ   ÚDEFAULT_MAX_LENGTHZempty_strings_allowedÚautoÚversionÚnodeÚ	clock_seqÚ	namespaceÚ	uuid_namerY   rZ   )r   r¦   rƒ   r©   rª   r«   r¬   r­   r®   r7   r8   r[   r   r   rZ   ì  s    
zUUIDFieldMixin.__init__c                 C   sŒ   | j r| j dkrt ¡ S | j dkr2t | j| j¡S | j dkrFtdƒ‚nB| j dkr`t | j| j	¡S | j dkrzt 
| j| j	¡S td| j  ƒ‚d S )Nr¥   é   rr   ú UUID version 2 is not supported.é   é   úUUID version %s is not valid.)rª   ÚuuidÚuuid4Úuuid1r«   r¬   r¢   Úuuid3r­   r®   Úuuid5r   r   r   r   Úcreate_uuid  s    




zUUIDFieldMixin.create_uuidc                    sf   t ƒ  ||¡}| jr>|r>|d u r>t|  ¡ ƒ}t|| j|ƒ |S | jrb|sbt|  ¡ ƒ}t|| j|ƒ |S r   )rY   r~   r©   r   r¹   r5   r+   r}   r[   r   r   r~     s    
zUUIDFieldMixin.pre_savec                    s   | j r
d S tƒ jf i |¤ŽS r   )r©   rY   Ú	formfield)r   r8   r[   r   r   rº     s    zUUIDFieldMixin.formfieldc                    s®   t ƒ  ¡ \}}}}| dd ¡| jkr*|d= | jdur>| j|d< | jdkrR| j|d< | jd urf| j|d< | jd urz| j|d< | jd urŽ| j|d< | j	d ur¢| j
|d	< ||||fS )
Nrv   Tr©   r¥   rª   r«   r¬   r­   r®   )rY   r   Úgetr¨   r©   rª   r«   r¬   r­   r®   rƒ   r‚   r[   r   r   r   #  s     











zUUIDFieldMixin.deconstruct)NNTr¥   NNNN)r?   r@   rA   r…   r¨   rZ   r¹   r~   rº   r   r†   r   r   r[   r   r£   à  s   	  ÿr£   c                       s,   e Zd ZdZdZ‡ fdd„Zdd„ Z‡  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                    s0   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 ?)rv   )rY   rZ   ÚHAS_SHORT_UUIDr   rQ   r¨   r   r[   r   r   rZ   C  s    zShortUUIDField.__init__c                 C   s|   | j r| j dkrt ¡ S | j dkr*t ¡ S | j dkr>tdƒ‚n:| j dkrRtdƒ‚n&| j dkrjtj| jdS td	| j  ƒ‚d S )
Nr¥   r¯   rr   r°   r±   z UUID version 3 is not supported.r²   )rƒ   r³   )rª   Ú	shortuuidr´   r¢   r­   r   r   r   r   r¹   I  s    





zShortUUIDField.create_uuid)r?   r@   rA   r…   r¨   rZ   r¹   r†   r   r   r[   r   r¼   8  s   r¼   )%r…   r]   r”   r´   r§   ÚImportErrorr¿   r¾   Zdjango.confr   Zdjango.core.exceptionsr   Zdjango.db.modelsr   r   r   r   r   Zdjango.db.models.constantsr	   Zdjango.template.defaultfiltersr
   Zdjango.utils.cryptor   Zdjango.utils.encodingr   r   rX   r   rC   r‡   rœ   r    Ú	Exceptionr¢   r£   r¼   r   r   r   r   Ú<module>   s<   

: H X