3
=^(                 @   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l
mZ ddlmZ dd	 Zd
d ZG dd deZG dd deZG dd de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.
    )unicode_literals)	DataError)ugettext_lazy)unicode_to_repr)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-8app2_gc/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               @   sJ   e Zd ZdZedZdddZ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.Nexactc             C   s"   || _ d | _|p| j| _|| _d S )N)r   serializer_fieldmessagelookup)selfr   r   r   r   r   r   __init__,   s    zUniqueValidator.__init__c             C   s    |j d | _t|jdd| _dS )zr
        This hook is called by the serializer instance,
        prior to the validation call being made.
           instanceN)source_attrs
field_namegetattrparentr   )r   r   r   r   r   set_context2   s    zUniqueValidator.set_contextc             C   s    d| j | jf |i}t|f|S )zT
        Filter the queryset to all instances matching the given attribute.
        z%s__%s)r   r   r   )r   valuer   filter_kwargsr   r   r   filter_queryset=   s    zUniqueValidator.filter_querysetc             C   s   | j dk	r|j| 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)r   excluder%   )r   r   r   r   r   exclude_current_instanceD   s    
z(UniqueValidator.exclude_current_instancec             C   s6   | j }| j||}| j|}t|r2t| jddd S )Nunique)code)r   r$   r'   r   r   r   )r   r"   r   r   r   r   __call__M   s
    
zUniqueValidator.__call__c             C   s   t d| jjt| jf S )Nz<%s(queryset=%s)>)r   	__class____name__r   r   )r   r   r   r   __repr__T   s    zUniqueValidator.__repr__)Nr   )r,   
__module____qualname____doc___r   r   r!   r$   r'   r*   r-   r   r   r   r   r   $   s   
	r   c               @   sZ   e Zd ZdZedZedZdddZ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.Nc             C   s"   || _ || _d | _|p| j| _d S )N)r   fieldsr   r   )r   r   r3   r   r   r   r   r   d   s    z UniqueTogetherValidator.__init__c             C   s   t |dd| _dS )zr
        This hook is called by the serializer instance,
        prior to the validation call being made.
        r   N)r   r   )r   
serializerr   r   r   r!   j   s    z#UniqueTogetherValidator.set_contextc                s8   j dk	rdS  fddjD }|r4t|dddS )z~
        The `UniqueTogetherValidator` always forces an implied 'required'
        state on the fields it applies to.
        Nc                s   i | ]}| krj |qS r   )missing_message).0r   )attrsr   r   r   
<dictcomp>z   s   zCUniqueTogetherValidator.enforce_required_fields.<locals>.<dictcomp>required)r)   )r   r3   r   )r   r7   missing_itemsr   )r7   r   r   enforce_required_fieldsr   s    

z/UniqueTogetherValidator.enforce_required_fieldsc                sR   | j dk	r2x&| jD ]}| krt| j | |< qW  fdd| jD }t|f|S )zU
        Filter the queryset to all instances matching the given attributes.
        Nc                s   i | ]} | |qS r   r   )r6   r   )r7   r   r   r8      s   z;UniqueTogetherValidator.filter_queryset.<locals>.<dictcomp>)r   r3   r   r   )r   r7   r   r   r#   r   )r7   r   r$      s    


z'UniqueTogetherValidator.filter_querysetc             C   s   | j dk	r|j| 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%   )r   r7   r   r   r   r   r'      s    
z0UniqueTogetherValidator.exclude_current_instancec                sx    j |  j} j||} j||} fdd|j D }d |krtt|rtdj j} jj	|d}t
|ddd S )Nc                s   g | ]\}}| j kr|qS r   )r3   )r6   fieldr"   )r   r   r   
<listcomp>   s    z4UniqueTogetherValidator.__call__.<locals>.<listcomp>z, )field_namesr(   )r)   )r;   r   r$   r'   itemsr   joinr3   r   formatr   )r   r7   r   Zchecked_valuesr>   r   r   )r   r   r*      s    
z UniqueTogetherValidator.__call__c             C   s"   t d| jjt| jt| jf S )Nz<%s(queryset=%s, fields=%s)>)r   r+   r,   r   r   r3   )r   r   r   r   r-      s    z UniqueTogetherValidator.__repr__)N)r,   r.   r/   r0   r1   r   r5   r   r!   r;   r$   r'   r*   r-   r   r   r   r   r2   [   s   
	r2   c               @   sR   e Zd ZdZedZdddZ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.c             C   s"   || _ || _|| _|p| j| _d S )N)r   r<   
date_fieldr   )r   r   r<   rC   r   r   r   r   r      s    zBaseUniqueForValidator.__init__c             C   s:   |j | j jd | _|j | j jd | _t|dd| _dS )zr
        This hook is called by the serializer instance,
        prior to the validation call being made.
        r   r   Nr   r   )r3   r<   r   r   rC   date_field_namer   r   )r   r4   r   r   r   r!      s    z"BaseUniqueForValidator.set_contextc                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   )r5   )r6   r   )r7   r   r   r   r8      s   zBBaseUniqueForValidator.enforce_required_fields.<locals>.<dictcomp>r9   )r)   N)r<   rC   r   )r   r7   r:   r   )r7   r   r   r;      s    z.BaseUniqueForValidator.enforce_required_fieldsc             C   s   t dd S )Nz&`filter_queryset` must be implemented.)NotImplementedError)r   r7   r   r   r   r   r$      s    z&BaseUniqueForValidator.filter_querysetc             C   s   | j dk	r|j| 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%   )r   r7   r   r   r   r   r'      s    
z/BaseUniqueForValidator.exclude_current_instancec             C   sV   | j | | j}| j||}| j||}t|rR| jj| jd}t| j	|iddd S )N)rC   r(   )r)   )
r;   r   r$   r'   r   r   rA   rC   r   r<   )r   r7   r   r   r   r   r   r*      s    
zBaseUniqueForValidator.__call__c             C   s*   t 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   r<   rC   )r   r   r   r   r-      s
    zBaseUniqueForValidator.__repr__)N)r,   r.   r/   r   r1   r5   r   r!   r;   r$   r'   r*   r-   r   r   r   r   rB      s   
	rB   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   s^   || j  }|| j }i }||| j< |j|d| j < |j|d| j < |j|d| j < t|f|S )Nz%s__dayz	%s__monthz%s__year)r<   rC   r   dayrD   monthyearr   )r   r7   r   r"   dater#   r   r   r   r$      s    


z&UniqueForDateValidator.filter_querysetN)r,   r.   r/   r1   r   r$   r   r   r   r   rF      s   rF   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< |j|d| j < t|f|S )Nz	%s__month)r<   rC   r   rH   rD   r   )r   r7   r   r"   rJ   r#   r   r   r   r$   	  s    


z'UniqueForMonthValidator.filter_querysetN)r,   r.   r/   r1   r   r$   r   r   r   r   rK     s   rK   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< |j|d| j < t|f|S )Nz%s__year)r<   rC   r   rI   rD   r   )r   r7   r   r"   rJ   r#   r   r   r   r$     s    


z&UniqueForYearValidator.filter_querysetN)r,   r.   r/   r1   r   r$   r   r   r   r   rL     s   rL   N)r0   
__future__r   Z	django.dbr   Zdjango.utils.translationr   r1   Zrest_framework.compatr   Zrest_framework.exceptionsr   Z#rest_framework.utils.representationr   r   r   objectr   r2   rB   rF   rK   rL   r   r   r   r   <module>   s   7YC