U
    7h8Q                     @   s^  d Z ddlZddlZzddlZdZW n ek
r<   dZY nX zddlZdZW n ek
rf   dZY nX 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_ATTEMPTSd   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   ^/var/www/formularioweb/env/lib/python3.8/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|kr.|D ]}t |d ||< q@q.t }	t jdd }
|
rt	dd |
}|D ]4}j|j
kr fdd|j
D }|	tf |M }	qt|}||j< |r|j	|	f|rt|}||j< qt 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   s8    
 
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 k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|| 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>   s     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rt 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   s:    


  
zAutoSlugField.create_slugc                 C   sz   t |rd|| S |t}|}|D ]<}zt||}W q& tk
r`   td||||Y q&X q&t |rvd|  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k	rBd|d< | jdk	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 kr8td| j|d< |dd| _| d |d	d| _| d	 | jr| jrtd
|dd| _| d |dd| _| d |dd| _	|dd| _
| d |dt| _d|krd|d< t j|| 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|k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| |st|}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kr6| j|d< | jdkrJ| j|d< | jdkr^| j|d< | jdkrr| j|d< | jdkr| j|d	< | jdk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| f|| 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k	r$d|d< | jdk	r6d|d< | jdk	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| f|| 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k	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 k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 |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k	r>| j|d< | jdkrR| j|d< | jd k	rf| j|d< | jd k	rz| j|d< | jd k	r| j|d< | j	d k	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                    s,   t  j|| 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