o
    isS                     @   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w zddlZdZW n ey1   dZY n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 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_str$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   d/var/www/html/formularioweb/env/lib/python3.10/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 | ]}|j r|js|jr|jr||j kr|jnd fqS N)is_relation
one_to_onemany_to_onerelated_modelmodel).0f	model_clsr   r   
<listcomp>.   s    z0UniqueFieldMixin._get_fields.<locals>.<listcomp>)_meta
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'   _default_managerall)r   r#   
slug_fieldfieldr   r   r   r   get_queryset4   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 ]}j|j
v r] fdd|j
D }|	tdi |M }	qAt|}||j< |rr|j	|	fi |rt|}||j< |rr|j	|	fi |srt j| |S )N)pkconstraintsc                 S   s
   t | tS r   )r   r   )cr   r   r   <lambda>M   s   
 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>Q   s
    
z0UniqueFieldMixin.find_unique.<locals>.<dictcomp>r   )r,   	__class__r-   excluder%   unique_togetherr1   r   r   filterfieldsnextsetattr)r   r3   r+   iteratorargsquerysetkwargsparamsparamqueryr.   unique_constraintsunique_constraint	conditionnewr   r2   r   find_unique:   s<   


zUniqueFieldMixin.find_uniqueN)__name__
__module____qualname__r   staticmethodr'   r,   rG   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 rtd|| _t|s:t|ttfs+|f}tdd |D s:t	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>   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
   rS   rT   rV   r   rW   rX   MAX_UNIQUE_QUERY_ATTEMPTSrY   super__init__)r   r=   r?   rO   r5   r   r   rc      s6   


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escaperT   sub)r   valuere_sepr   r   r   _slug_strip   s   zAutoSlugField._slug_stripc                 C   s   | r|| S dS Nre   r   )contentrS   r   r   r   slugify_func   s   zAutoSlugField.slugify_funcc                 c   s    |V  t || jD ]2}|}d| j|f }t|}| jr3t|| | jkr3|d | j|  }| |}d||f }|V  q
td|| jf )Nz%s%sz&max slug attempts for %s exceeded (%s))rangerY   rT   lenslug_lenrk   RuntimeError)r   original_slugstartislugendend_lenr   r   r   slug_generator   s    
zAutoSlugField.slug_generatorc           
         s   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d}jt||}d}|j_jrV|d j }|}|}	jrit j| |S  ||	|S )NFTrS   c                    s   j  | dS )N)rS   )rn   get_slug_fields)lookup_valuer3   r   rS   r   r   r0      s    
z+AutoSlugField.create_slug.<locals>.<lambda>   )r   r1   rV   rW   r\   r   r^   r_   r%   	get_fieldrS   rT   joinmap
max_lengthrq   rk   rX   r;   rG   ry   )
r   r3   addrv   use_existing_slugrO   r*   slug_for_fieldrt   rs   r   r|   r   create_slug   s:   


zAutoSlugField.create_slugc                 C   sr   t |r
d|| S |t}|}|D ]}zt||}W q ty-   td||||w t |r7d|  S |S )Nz%szbvalue {} in AutoSlugField's 'populate_from' argument {} returned an error - {} has no attribute {})r]   splitr	   r   AttributeErrorr   )r   r3   r{   lookup_value_pathattrelemr   r   r   rz     s"   

zAutoSlugField.get_slug_fieldsc                 C   s   t | ||}|S r   )r   r   r   r3   r   ri   r   r   r   pre_save!  s   zAutoSlugField.pre_savec                 C      dS )Nr   r   r   r   r   r   get_internal_type%     zAutoSlugField.get_internal_typec                    s`   t   \}}}}| j|d< | jdks| j|d< | jdur!d|d< | jdur*d|d< ||||fS )NrO   rU   rT   FTrV   rX   )rb   deconstructr\   rT   rV   rX   r   namepathr=   r?   rd   r   r   r   (  s   




zAutoSlugField.deconstruct)rH   rI   rJ   __doc__rc   rk   rK   rn   ry   r   rz   r   r   r   __classcell__r   r   rd   r   rL   a   s    7!
0rL   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 rtd| j|d< |dd| _| d |d	d| _| d	 | jrC| jrCtd
|dd| _| d |dd| _| d |dd| _	|dd| _
| d |dt| _d|vr}d|d< t j|i | d S )NrM   TrN   Flengthzmissing 'length' argumentr   	lowercase	uppercasez@the 'lowercase' and 'uppercase' arguments are mutually exclusiveinclude_digitsinclude_alphainclude_punctuationkeep_defaultrY   unique)rZ   r[   r   r   r   r   r   r   r   r   r   ra   rY   rb   rc   r   r=   r?   rd   r   r   rc   W  s6   






zRandomCharField.__init__c                 c   s4    t | jD ]}dt| j|V  qtd| j )Nre   z+max random character attempts exceeded (%s))ro   rY   r   r   r   rr   )r   charsru   r   r   r   random_char_generatory  s   z%RandomCharField.random_char_generatorc                 C   s"   |j jD ]
}| j|v r dS qdS )NTF)r%   r7   r1   )r   r3   r@   r   r   r   in_unique_together  s
   
z"RandomCharField.in_unique_togetherc                 C   s   |r| j rt|| jdkrt|| jS d}| jr/| jr!|tj7 }n| jr*|tj7 }n|tj	7 }| j
r7|tj7 }| jr?|tj7 }| |}| jsY| |sYt|}t|| j| |S | ||j| j|S rl   )r   r   r1   r   r   stringascii_lowercaser   ascii_uppercaseascii_lettersr   digitsr   punctuationr   r   r   r:   r;   rG   r%   r~   )r   r3   r   
populationrandom_charsrF   r   r   r   r     s6   



zRandomCharField.pre_savec                 C   r   )Nr   r   r   r   r   r   internal_type  r   zRandomCharField.internal_typec                    s   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 r9| j|d< | jdu rC| j|d	< | jdu rM| j|d
< ||||fS )Nr   r   Tr   r   Fr   r   r   r   )	rb   r   r   r   r   r   r   r   r   r   rd   r   r   r     s    












zRandomCharField.deconstruct)rH   rI   rJ   r   rc   r   r   r   r   r   r   r   r   rd   r   r   4  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 )NrN   FrM   Tauto_now_addrZ   r   rc   r   r   r   r   rc     s   zCreationDateTimeField.__init__c                 C   r   Nr   r   r   r   r   r   r     r   z'CreationDateTimeField.get_internal_typec                    sT   t   \}}}}| jdurd|d< | jdurd|d< | jdur$d|d< ||||fS )NFTrN   rM   r   )rb   r   rN   rM   r   r   rd   r   r   r     s   


z!CreationDateTimeField.deconstruct)rH   rI   rJ   r   rc   r   r   r   r   r   rd   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   rc     s   z"ModificationDateTimeField.__init__c                 C   r   r   r   r   r   r   r   r     r   z+ModificationDateTimeField.get_internal_typec                    s0   t   \}}}}| jdurd|d< ||||fS )NFTr   )rb   r   r   r   rd   r   r   r     s   
z%ModificationDateTimeField.deconstructc                    s&   t |ddst || jS t ||S )Nupdate_modifiedT)r   r1   rb   r   )r   r3   r   rd   r   r   r     s   z"ModificationDateTimeField.pre_save)	rH   rI   rJ   r   rc   r   r   r   r   r   r   rd   r   r     s    r   c                   @   s   e Zd ZdS )UUIDVersionErrorN)rH   rI   rJ   r   r   r   r   r     s    r   c                       sd   e Zd ZdZdZ								d fdd	Zdd	 Z fd
dZd 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 |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   FTrM   rN   verbose_name)HAS_UUIDr   rZ   DEFAULT_MAX_LENGTHempty_strings_allowedautoversionnode	clock_seq	namespace	uuid_namerb   rc   )r   r   r   r   r   r   r   r   r   r=   r?   rd   r   r   rc     s    
zUUIDFieldMixin.__init__c                 C   s   | j r| j dkrt S | j dkrt| j| jS | j dkr"td| j dkr/t| j| j	S | j dkr<t
| j| j	S td| j  )Nr      r}    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r1|s1t|  }t|| j| |S r   )rb   r   r   r   r   r;   r1   r   rd   r   r   r   6  s   
zUUIDFieldMixin.pre_savec                    s    | j rd S t j||fi |S r   )r   rb   	formfield)r   
form_classchoices_form_classr?   rd   r   r   r   D  s   zUUIDFieldMixin.formfieldc                    s   t   \}}}}|dd | jkr|d= | jdur| j|d< | jdkr)| j|d< | jd ur3| j|d< | jd ur=| j|d< | jd urG| j|d< | j	d urQ| j
|d	< ||||fS )
Nr   Tr   r   r   r   r   r   r   )rb   r   getr   r   r   r   r   r   r   r   r   rd   r   r   r   I  s    











zUUIDFieldMixin.deconstruct)NNTr   NNNN)NN)rH   rI   rJ   r   r   rc   r   r   r   r   r   r   r   rd   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 ?)r   )rb   rc   HAS_SHORT_UUIDr   rZ   r   r   rd   r   r   rc   i  s   zShortUUIDField.__init__c                 C   st   | j r| j dkrt S | j dkrt S | j dkrtd| j dkr'td| j dkr3tj| jdS td	| j  )
Nr   r   r}   r   r   z UUID version 3 is not supported.r   )r   r   )r   	shortuuidr   r   r   r   r   r   r   r   r  s   



zShortUUIDField.create_uuid)rH   rI   rJ   r   r   rc   r   r   r   r   rd   r   r   ^  s
    	r   )%r   rf   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   ra   r   rL   r   r   r   	Exceptionr   r   r   r   r   r   r   <module>   sF   : T e