3
g8Q                 @   s^  d Z ddlZddlZyddlZdZW n ek
r<   dZY nX y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j|d S )Nz#'{}' argument must be True or False)
isinstancegetattrbool
ValueErrorformat)selfattrname r   b/var/www/tester-filtro-web/env/lib/python3.6/site-packages/django_extensions/db/fields/__init__.pycheck_is_bool%   s    zUniqueFieldMixin.check_is_boolc                s    fdd j j D S )Nc                s>   g | ]6}|j  s"|js"|jr|jr||j kr4|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_fields)r   r   )r   r   _get_fields)   s    zUniqueFieldMixin._get_fieldsc             C   s8   x,| j |D ]\}}|r||kr|jj S qW |jj S )N)r   Z_default_managerall)r   r   
slug_fieldfieldr   r   r   r   get_queryset0   s    zUniqueFieldMixin.get_querysetc                s  j  j|} jr"|j jd}i }x8 jjD ],}j|kr0x|D ]}t |d ||< qDW q0W t }	t jdd }
|
rt	dd |
}x<|D ]4}j|j
kr fdd|j
D }|	tf |M }	qW t|}||j< x,| s|j	|	f|rt|}||j< qW t j| |S )N)pkconstraintsc             S   s
   t | tS )N)r   r   )cr   r   r   <lambda>I   s    z.UniqueFieldMixin.find_unique.<locals>.<lambda>c                s$   i | ]}|j krt |d |qS )N)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   r   find_unique6   s2    




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   |j dd |j dd |jdd }|d kr6tdn|| _t|svt|ttfsX|f}tdd |D svt	d	| |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 j|| d S )NblankTeditableFpopulate_fromz missing 'populate_from' argumentc             s   s   | ]}t |tV  qd S )N)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
   rF   rG   rI   r   rJ   rK   MAX_UNIQUE_QUERY_ATTEMPTSrL   super__init__)r   r3   r4   rB   )r+   r   r   rV      s*    



zAutoSlugField.__init__c             C   s:   dt j| j }t jd| | j|}t j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escaperG   sub)r   valueZre_sepr   r   r   _slug_strip   s    zAutoSlugField._slug_stripc             C   s   | r|| S dS )NrW   r   )contentrF   r   r   r   slugify_func   s    zAutoSlugField.slugify_funcc             c   s   |V  xtt || jD ]d}|}d| j|f }t|}| jrft|| | jkrf|d | j|  }| j|}d||f }|V  qW td|| jf d S )Nz%s%sz&max slug attempts for %s exceeded (%s))rangerL   rG   lenslug_lenr\   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 r d}jr.|r.d}|r6|S j}t|ttfsP|f} jj	j}t  dj
 fdd}jjt||}d}|j_jr|d j }j|}|}	jrt j| |S j |j|	|S )NFTrF   c                s   j j | dS )N)rF   )r^   get_slug_fields)lookup_value)r)   r   rF   r   r   r'      s   
z+AutoSlugField.create_slug.<locals>.<lambda>   )r   r(   rI   rJ   rO   r   rQ   rR   r   	get_fieldrF   rG   joinmap
max_lengthra   r\   rK   r1   r:   rh   )
r   r)   addrf   Zuse_existing_slugrB   r!   Zslug_for_fieldrd   rc   r   )r)   r   rF   r   create_slug   s4    

zAutoSlugField.create_slugc             C   s~   t |rd|| S |jt}|}xD|D ]<}yt||}W q( tk
rb   tdj||||Y q(X q(W t |rzd|  S |S )Nz%szbvalue {} in AutoSlugField's 'populate_from' argument {} returned an error - {} has no attribute {})rP   splitr	   r   AttributeErrorr   )r   r)   rj   Zlookup_value_pathattrelemr   r   r   ri      s    


zAutoSlugField.get_slug_fieldsc             C   s   t | j||}|S )N)r   rq   )r   r)   rp   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 \}}}}| j|d< | jdks0| j|d< | jdk	rBd|d< | jdk	rTd|d< ||||fS )NrB   rH   rG   FTrI   rK   )rU   deconstructrO   rG   rI   rK   )r   namepathr3   r4   )r+   r   r   rx     s    




zAutoSlugField.deconstruct)r;   r<   r=   __doc__rV   r\   r>   r^   rh   rq   ri   rv   rw   rx   __classcell__r   r   )r+   r   r?   ]   s   6-r?   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  |j dd |j dd |jdd | _| jd kr8td| j|d< |jdd| _| jd |jd	d| _| jd	 | jr| jrtd
|jdd| _| jd |jdd| _| jd |jdd| _	|jdd| _
| jd |jdt| _d|krd|d< t j|| d S )Nr@   TrA   Flengthzmissing 'length' argumentro   	lowercase	uppercasez@the 'lowercase' and 'uppercase' arguments are mutually exclusiveinclude_digitsinclude_alphainclude_punctuationkeep_defaultrL   unique)rM   rN   r~   r   r   r   r   r   r   r   r   rT   rL   rU   rV   )r   r3   r4   )r+   r   r   rV   G  s.    






zRandomCharField.__init__c             c   s:   x&t | jD ]}djt| j|V  qW td| j d S )NrW   z+max random character attempts exceeded (%s))r_   rL   rm   r   r~   rb   )r   charsre   r   r   r   random_char_generatore  s    z%RandomCharField.random_char_generatorc             C   s$   x|j jD ]}| j|kr
dS q
W dS )NTF)r   r-   r(   )r   r)   r5   r   r   r   in_unique_togetherj  s    
z"RandomCharField.in_unique_togetherc             C   s   | s| j r(t|| jdkr(t|| jS d}| jr`| jrD|tj7 }n| jrV|tj7 }n
|tj	7 }| j
rp|tj7 }| jr|tj7 }| j|}| j r| j| rt|}t|| j| |S | j||jj| j|S )NrW   )r   r   r(   r   r   stringascii_lowercaser   ascii_uppercaseascii_lettersr   digitsr   punctuationr   r   r   r0   r1   r:   r   rl   )r   r)   rp   
populationZrandom_charsr9   r   r   r   rv   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 \}}}}| 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~   ro   Tr   r   Fr   r   r   r   )	rU   rx   r~   r   r   r   r   r   r   )r   ry   rz   r3   r4   )r+   r   r   rx     s     












zRandomCharField.deconstruct)r;   r<   r=   r{   rV   r   r   rv   r   rx   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:   |j dd |j dd |j dd tj| f|| d S )NrA   Fr@   Tauto_now_add)rM   r   rV   )r   r3   r4   r   r   r   rV     s    zCreationDateTimeField.__init__c             C   s   dS )Nr   r   )r   r   r   r   rw     s    z'CreationDateTimeField.get_internal_typec                sT   t  j \}}}}| jdk	r$d|d< | jdk	r6d|d< | jdk	rHd|d< ||||fS )NFTrA   r@   r   )rU   rx   rA   r@   r   )r   ry   rz   r3   r4   )r+   r   r   rx     s    


z!CreationDateTimeField.deconstruct)r;   r<   r=   r{   rV   rw   rx   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"   |j dd tj| f|| d S )Nauto_nowT)rM   r   rV   )r   r3   r4   r   r   r   rV     s    z"ModificationDateTimeField.__init__c             C   s   dS )Nr   r   )r   r   r   r   rw     s    z+ModificationDateTimeField.get_internal_typec                s0   t  j \}}}}| jdk	r$d|d< ||||fS )NFTr   )rU   rx   r   )r   ry   rz   r3   r4   )r+   r   r   rx     s    
z%ModificationDateTimeField.deconstructc                s&   t |ddst || jS t j||S )NZupdate_modifiedT)r   r(   rU   rv   )r   r)   rp   )r+   r   r   rv     s    z"ModificationDateTimeField.pre_save)	r;   r<   r=   r{   rV   rw   rx   rv   r|   r   r   )r+   r   r     s
   r   c               @   s   e Zd ZdS )UUIDVersionErrorN)r;   r<   r=   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|
jd| j |r8d| _d|
d< |
j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 ?)ro   FTr@   rA   verbose_name)HAS_UUIDr   rM   DEFAULT_MAX_LENGTHZempty_strings_allowedautoversionnode	clock_seq	namespace	uuid_namerU   rV   )r   r   ry   r   r   r   r   r   r   r3   r4   )r+   r   r   rV     s    
zUUIDFieldMixin.__init__c             C   s   | j  s| j dkrtj S | j dkr4tj| j| jS | j dkrHtdnB| j dkrbtj| j| j	S | j dkr|tj
| j| j	S td| j  d S )Nr      rk   z UUID version 2 is not supported.      zUUID version %s is not valid.)r   uuiduuid4uuid1r   r   r   uuid3r   r   uuid5)r   r   r   r   create_uuid  s    




zUUIDFieldMixin.create_uuidc                sh   t  j||}| jr>|r>|d kr>t| j }t|| j| |S | jrd| rdt| j }t|| j| |S )N)rU   rv   r   r   r   r1   r(   )r   r)   rp   r[   )r+   r   r   rv     s    zUUIDFieldMixin.pre_savec                s   | j r
d S t jf |S )N)r   rU   	formfield)r   r4   )r+   r   r   r     s    zUUIDFieldMixin.formfieldc                s   t  j \}}}}|j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 )
Nro   Tr   r   r   r   r   r   r   )rU   rx   getr   r   r   r   r   r   r   ry   )r   ry   rz   r3   r4   )r+   r   r   rx   #  s     











zUUIDFieldMixin.deconstruct)NNTr   NNNN)r;   r<   r=   r{   r   rV   r   rv   r   rx   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|jd| j d S )Nza'shortuuid' module is required for ShortUUIDField. (Do you have Python 2.5 or higher installed ?)ro   )rU   rV   HAS_SHORT_UUIDr   rM   r   )r   r3   r4   )r+   r   r   rV   C  s    zShortUUIDField.__init__c             C   s~   | j  s| j dkrtj S | j dkr,tj S | j dkr@tdn:| j dkrTtdn&| j dkrltj| jdS td	| j  d S )
Nr   r   rk   z UUID version 2 is not supported.r   z UUID version 3 is not supported.r   )ry   zUUID version %s is not valid.)r   	shortuuidr   r   r   )r   r   r   r   r   I  s    





zShortUUIDField.create_uuid)r;   r<   r=   r{   r   rV   r   r|   r   r   )r+   r   r   8  s   r   )%r{   rX   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   rT   r   r?   r}   r   r   	Exceptionr   r   r   r   r   r   r   <module>   s<   

: H X