3
Ah`b(                 @   s   d Z ddlmZ ddlmZ ddlmZ ddlm	Z	 dd Z
dd	 ZG d
d dZG dd dZG dd dZG dd dZG dd deZG dd deZG dd deZdS )aK  
We perform uniqueness checks explicitly on the serializer class, rather
the using Django's `.full_clean()`.

This gives us better separation of concerns, allows us to use single-step
object creation, and makes it possible to switch between using the implicit
`ModelSerializer` class and an equivalent explicit `Serializer` class.
    )	DataError)gettext_lazy)ValidationError)
smart_reprc             C   s(   y| j  S  tttfk
r"   dS X d S )NF)exists	TypeError
ValueErrorr   )queryset r
   H/tmp/pip-build-9m32_hle/djangorestframework/rest_framework/validators.py	qs_exists   s    r   c             K   s0   y| j f |S  tttfk
r*   | j S X d S )N)filterr   r   r   none)r	   kwargsr
   r
   r   	qs_filter   s    r   c               @   sF   e Zd ZdZedZdZdddZdd	 Zd
d Z	dd Z
dd ZdS )UniqueValidatorz
    Validator that corresponds to `unique=True` on a model field.

    Should be applied to an individual field on the serializer.
    zThis field must be unique.TNexactc             C   s   || _ |p| j| _|| _d S )N)r	   messagelookup)selfr	   r   r   r
   r
   r   __init__*   s    zUniqueValidator.__init__c             C   s   d|| j f |i}t|f|S )zT
        Filter the queryset to all instances matching the given attribute.
        z%s__%s)r   r   )r   valuer	   
field_namefilter_kwargsr
   r
   r   filter_queryset/   s    zUniqueValidator.filter_querysetc             C   s   |dk	r|j |jdS |S )z}
        If an instance is being updated, then do not include
        that instance itself as a uniqueness conflict.
        N)pk)excluder   )r   r	   instancer
   r
   r   exclude_current_instance6   s    z(UniqueValidator.exclude_current_instancec             C   sR   |j d }t|jdd }| j}| j|||}| j||}t|rNt| jddd S )N   r   unique)code)	source_attrsgetattrparentr	   r   r   r   r   r   )r   r   Zserializer_fieldr   r   r	   r
   r
   r   __call__?   s    
zUniqueValidator.__call__c             C   s   d| j jt| jf S )Nz<%s(queryset=%s)>)	__class____name__r   r	   )r   r
   r
   r   __repr__L   s    zUniqueValidator.__repr__)Nr   )r(   
__module____qualname____doc___r   requires_contextr   r   r   r&   r)   r
   r
   r
   r   r   !   s   
	r   c               @   sV   e Zd ZdZedZedZdZdddZdd	 Z	d
d Z
dd Zdd Zdd ZdS )UniqueTogetherValidatorz
    Validator that corresponds to `unique_together = (...)` on a model class.

    Should be applied to the serializer class, not to an individual field.
    z0The fields {field_names} must make a unique set.zThis field is required.TNc             C   s   || _ || _|p| j| _d S )N)r	   fieldsr   )r   r	   r0   r   r
   r
   r   r   ]   s    z UniqueTogetherValidator.__init__c                s:   j dk	rdS  fddjD }|r6t|dddS )z~
        The `UniqueTogetherValidator` always forces an implied 'required'
        state on the fields it applies to.
        Nc                s$   i | ]}j | j krj|qS r
   )r0   sourcemissing_message).0r   )attrsr   
serializerr
   r   
<dictcomp>j   s   zCUniqueTogetherValidator.enforce_required_fields.<locals>.<dictcomp>required)r!   )r   r0   r   )r   r4   r5   missing_itemsr
   )r4   r   r5   r   enforce_required_fieldsb   s    

z/UniqueTogetherValidator.enforce_required_fieldsc                sb   fdd| j D }jdk	rDx$|D ]}| kr$tj| |< q$W  fdd|D }t|f|S )zU
        Filter the queryset to all instances matching the given attributes.
        c                s   g | ]} j | jqS r
   )r0   r1   )r3   r   )r5   r
   r   
<listcomp>x   s   z;UniqueTogetherValidator.filter_queryset.<locals>.<listcomp>Nc                s   i | ]} | |qS r
   r
   )r3   r1   )r4   r
   r   r6      s   z;UniqueTogetherValidator.filter_queryset.<locals>.<dictcomp>)r0   r   r$   r   )r   r4   r	   r5   sourcesr1   r   r
   )r4   r5   r   r   r   s    




z'UniqueTogetherValidator.filter_querysetc             C   s   |dk	r|j |jdS |S )z}
        If an instance is being updated, then do not include
        that instance itself as a uniqueness conflict.
        N)r   )r   r   )r   r4   r	   r   r
   r
   r   r      s    z0UniqueTogetherValidator.exclude_current_instancec                s    j ||  j} j|||} j|||j} fdd|j D }d |kr|t|r|dj j} j	j
|d}t|ddd S )Nc                s   g | ]\}}| j kr|qS r
   )r0   )r3   fieldr   )r   r
   r   r:      s    z4UniqueTogetherValidator.__call__.<locals>.<listcomp>z, )field_namesr    )r!   )r9   r	   r   r   r   itemsr   joinr0   r   formatr   )r   r4   r5   r	   Zchecked_valuesr=   r   r
   )r   r   r&      s    z UniqueTogetherValidator.__call__c             C   s   d| j jt| jt| jf S )Nz<%s(queryset=%s, fields=%s)>)r'   r(   r   r	   r0   )r   r
   r
   r   r)      s    z UniqueTogetherValidator.__repr__)N)r(   r*   r+   r,   r-   r   r2   r.   r   r9   r   r   r&   r)   r
   r
   r
   r   r/   S   s   
	r/   c               @   s    e Zd ZedZdZdd ZdS )$ProhibitSurrogateCharactersValidatorz7Surrogate characters are not allowed: U+{code_point:X}.Z surrogate_characters_not_allowedc             C   s@   x:dd t |D D ]$}| jjt|d}t|| jdqW d S )Nc             s   s.   | ]&}d t |  kodkn  r|V  qdS )i   i  N)ord)r3   chr
   r
   r   	<genexpr>   s    z@ProhibitSurrogateCharactersValidator.__call__.<locals>.<genexpr>)
code_point)r!   )strr   r@   rB   r   r!   )r   r   Zsurrogate_characterr   r
   r
   r   r&      s    z-ProhibitSurrogateCharactersValidator.__call__N)r(   r*   r+   r-   r   r!   r&   r
   r
   r
   r   rA      s   rA   c               @   sN   e Zd ZdZedZdZdddZdd Zdd	 Z	d
d Z
dd Zdd ZdS )BaseUniqueForValidatorNzThis field is required.Tc             C   s"   || _ || _|| _|p| j| _d S )N)r	   r<   
date_fieldr   )r   r	   r<   rH   r   r
   r
   r   r      s    zBaseUniqueForValidator.__init__c                s0    fddj jgD }|r,t|dddS )z
        The `UniqueFor<Range>Validator` classes always force an implied
        'required' state on the fields they are applied to.
        c                s   i | ]}| krj |qS r
   )r2   )r3   r   )r4   r   r
   r   r6      s   zBBaseUniqueForValidator.enforce_required_fields.<locals>.<dictcomp>r7   )r!   N)r<   rH   r   )r   r4   r8   r
   )r4   r   r   r9      s    z.BaseUniqueForValidator.enforce_required_fieldsc             C   s   t dd S )Nz&`filter_queryset` must be implemented.)NotImplementedError)r   r4   r	   r   date_field_namer
   r
   r   r      s    z&BaseUniqueForValidator.filter_querysetc             C   s   |dk	r|j |jdS |S )z}
        If an instance is being updated, then do not include
        that instance itself as a uniqueness conflict.
        N)r   )r   r   )r   r4   r	   r   r
   r
   r   r      s    z/BaseUniqueForValidator.exclude_current_instancec             C   s   |j | j jd }|j | j jd }| j| | j}| j||||}| j|||j}t	|r~| j
j| jd}t| j|iddd S )Nr   )rH   r    )r!   r"   r"   )r0   r<   r#   rH   r9   r	   r   r   r   r   r   r@   r   )r   r4   r5   r   rJ   r	   r   r
   r
   r   r&      s    
zBaseUniqueForValidator.__call__c             C   s&   d| j jt| jt| jt| jf S )Nz*<%s(queryset=%s, field=%s, date_field=%s)>)r'   r(   r   r	   r<   rH   )r   r
   r
   r   r)      s
    zBaseUniqueForValidator.__repr__)N)r(   r*   r+   r   r-   r2   r.   r   r9   r   r   r&   r)   r
   r
   r
   r   rG      s   
	rG   c               @   s   e Zd ZedZdd ZdS )UniqueForDateValidatorz6This field must be unique for the "{date_field}" date.c             C   sV   || j  }|| j }i }|||< |j|d| < |j|d| < |j|d| < t|f|S )Nz%s__dayz	%s__monthz%s__year)r<   rH   daymonthyearr   )r   r4   r	   r   rJ   r   dater   r
   r
   r   r      s    

z&UniqueForDateValidator.filter_querysetN)r(   r*   r+   r-   r   r   r
   r
   r
   r   rK      s   rK   c               @   s   e Zd ZedZdd ZdS )UniqueForMonthValidatorz7This field must be unique for the "{date_field}" month.c             C   s:   || j  }|| j }i }|||< |j|d| < t|f|S )Nz	%s__month)r<   rH   rM   r   )r   r4   r	   r   rJ   r   rO   r   r
   r
   r   r     s    

z'UniqueForMonthValidator.filter_querysetN)r(   r*   r+   r-   r   r   r
   r
   r
   r   rP     s   rP   c               @   s   e Zd ZedZdd ZdS )UniqueForYearValidatorz6This field must be unique for the "{date_field}" year.c             C   s:   || j  }|| j }i }|||< |j|d| < t|f|S )Nz%s__year)r<   rH   rN   r   )r   r4   r	   r   rJ   r   rO   r   r
   r
   r   r     s    

z&UniqueForYearValidator.filter_querysetN)r(   r*   r+   r-   r   r   r
   r
   r
   r   rQ     s   rQ   N)r,   Z	django.dbr   Zdjango.utils.translationr   r-   Zrest_framework.exceptionsr   Z#rest_framework.utils.representationr   r   r   r   r/   rA   rG   rK   rP   rQ   r
   r
   r
   r   <module>   s   2W=