3
=^                 @   s   d dl mZ d dl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	lm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 )    )unicode_literalsN)ugettext_lazy)
exceptions)unicode_http_header)_reverse)api_settings)replace_query_param)
_MediaTypec               @   s8   e Zd ZejZejZejZ	dd Z
dddZdd ZdS )	BaseVersioningc             O   s   d}t |j| jjdd S )Nz.{cls}.determine_version() must be implemented.)cls)NotImplementedErrorformat	__class____name__)selfrequestargskwargsmsg r   H/tmp/pip-build-8app2_gc/djangorestframework/rest_framework/versioning.pydetermine_version   s    z BaseVersioning.determine_versionNc             K   s   t |||||f|S )N)r   )r   viewnamer   r   r   r   extrar   r   r   reverse   s    zBaseVersioning.reversec             C   s&   | j s
dS |d k	r|| jkp$|| j kS )NT)allowed_versionsdefault_version)r   versionr   r   r   is_allowed_version   s    z!BaseVersioning.is_allowed_version)NNNN)r   
__module____qualname__r   DEFAULT_VERSIONr   ZALLOWED_VERSIONSr   ZVERSION_PARAMversion_paramr   r   r   r   r   r   r   r
      s   
r
   c               @   s    e Zd ZdZedZdd ZdS )AcceptHeaderVersioningzb
    GET /something/ HTTP/1.1
    Host: example.com
    Accept: application/json; version=1.0
    z#Invalid version in "Accept" header.c             O   s>   t |j}|jj| j| j}t|}| j|s:tj	| j
|S )N)r	   Zaccepted_media_typeparamsgetr"   r   r   r   r   ZNotAcceptableinvalid_version_message)r   r   r   r   
media_typer   r   r   r   r   -   s    

z(AcceptHeaderVersioning.determine_versionN)r   r   r    __doc___r&   r   r   r   r   r   r#   %   s   r#   c                   s2   e Zd ZdZedZdd Zd fdd	Z  ZS )	URLPathVersioninga0  
    To the client this is the same style as `NamespaceVersioning`.
    The difference is in the backend - this implementation uses
    Django's URL keyword arguments to determine the version.

    An example URL conf for two views that accept two different versions.

    urlpatterns = [
        url(r'^(?P<version>[v1|v2]+)/users/$', users_list, name='users-list'),
        url(r'^(?P<version>[v1|v2]+)/users/(?P<pk>[0-9]+)/$', users_detail, name='users-detail')
    ]

    GET /1.0/something/ HTTP/1.1
    Host: example.com
    Accept: application/json
    zInvalid version in URL path.c             O   s8   |j | j| j}|d kr| j}| j|s4tj| j|S )N)r%   r"   r   r   r   NotFoundr&   )r   r   r   r   r   r   r   r   r   L   s    
z#URLPathVersioning.determine_versionNc                sB   |j d k	r&|d kri n|}|j || j< tt| j|||||f|S )N)r   r"   superr*   r   )r   r   r   r   r   r   r   )r   r   r   r   U   s
    

zURLPathVersioning.reverse)NNNN)	r   r   r    r(   r)   r&   r   r   __classcell__r   r   )r   r   r*   9   s   	r*   c                   s:   e Zd ZdZedZdd Zd
 fdd	Zdd	 Z  Z	S )NamespaceVersioninga  
    To the client this is the same style as `URLPathVersioning`.
    The difference is in the backend - this implementation uses
    Django's URL namespaces to determine the version.

    An example URL conf that is namespaced into two separate versions

    # users/urls.py
    urlpatterns = [
        url(r'^/users/$', users_list, name='users-list'),
        url(r'^/users/(?P<pk>[0-9]+)/$', users_detail, name='users-detail')
    ]

    # urls.py
    urlpatterns = [
        url(r'^v1/', include('users.urls', namespace='v1')),
        url(r'^v2/', include('users.urls', namespace='v2'))
    ]

    GET /1.0/something/ HTTP/1.1
    Host: example.com
    Accept: application/json
    zBInvalid version in URL path. Does not match any version namespace.c             O   sZ   t |dd }|d ks|j r"| jS |jjd}x|D ]}| j|r4|S q4W tj| jd S )Nresolver_match:)getattr	namespacer   splitr   r   r+   r&   )r   r   r   r   r/   Zpossible_versionsr   r   r   r   r   y   s    

z%NamespaceVersioning.determine_versionNc                s2   |j d k	r| j||}tt| j|||||f|S )N)r   get_versioned_viewnamer,   r.   r   )r   r   r   r   r   r   r   )r   r   r   r      s    

zNamespaceVersioning.reversec             C   s   |j d | S )Nr0   )r   )r   r   r   r   r   r   r4      s    z*NamespaceVersioning.get_versioned_viewname)NNNN)
r   r   r    r(   r)   r&   r   r   r4   r-   r   r   )r   r   r.   _   s
   r.   c               @   s*   e Zd ZdZejdZedZdd Z	dS )HostNameVersioningzX
    GET /something/ HTTP/1.1
    Host: v1.example.com
    Accept: application/json
    z,^([a-zA-Z0-9]+)\.[a-zA-Z0-9]+\.[a-zA-Z0-9]+$zInvalid version in hostname.c       	      O   sN   |j  jd\}}}| jj|}|s*| jS |jd}| j|sJtj| j	|S )Nr0      )
get_host	partitionhostname_regexmatchr   groupr   r   r+   r&   )	r   r   r   r   hostname	separatorportr:   r   r   r   r   r      s    

z$HostNameVersioning.determine_versionN)
r   r   r    r(   recompiler9   r)   r&   r   r   r   r   r   r5      s   
r5   c                   s2   e Zd ZdZedZdd Zd fdd	Z  ZS )	QueryParameterVersioningza
    GET /something/?version=0.1 HTTP/1.1
    Host: example.com
    Accept: application/json
    z#Invalid version in query parameter.c             O   s,   |j j| j| j}| j|s(tj| j|S )N)Zquery_paramsr%   r"   r   r   r   r+   r&   )r   r   r   r   r   r   r   r   r      s    
z*QueryParameterVersioning.determine_versionNc                s:   t t| j|||||f|}|jd k	r6t|| j|jS |S )N)r,   rA   r   r   r   r"   )r   r   r   r   r   r   r   url)r   r   r   r      s
    

z QueryParameterVersioning.reverse)NNNN)	r   r   r    r(   r)   r&   r   r   r-   r   r   )r   r   rA      s   rA   )
__future__r   r?   Zdjango.utils.translationr   r)   Zrest_frameworkr   Zrest_framework.compatr   Zrest_framework.reverser   Zrest_framework.settingsr   Z*rest_framework.templatetags.rest_frameworkr   Zrest_framework.utils.mediatypesr	   objectr
   r#   r*   r.   r5   rA   r   r   r   r   <module>   s   &1