3
=^                 @   sp   d Z ddlmZ ddlmZ ddlmZmZ ddlm	Z	 ddl
mZmZmZ G dd deZG d	d
 d
eZdS )z
Content negotiation deals with selecting an appropriate renderer given the
incoming request.  Typically this will be based on the request's Accept header.
    )unicode_literals)Http404)HTTP_HEADER_ENCODING
exceptions)api_settings)
_MediaTypemedia_type_matchesorder_by_precedencec               @   s   e Zd Zdd ZdddZdS )BaseContentNegotiationc             C   s   t dd S )Nz$.select_parser() must be implemented)NotImplementedError)selfrequestparsers r   I/tmp/pip-build-8app2_gc/djangorestframework/rest_framework/negotiation.pyselect_parser   s    z$BaseContentNegotiation.select_parserNc             C   s   t dd S )Nz&.select_renderer() must be implemented)r   )r   r   	renderersformat_suffixr   r   r   select_renderer   s    z&BaseContentNegotiation.select_renderer)N)__name__
__module____qualname__r   r   r   r   r   r   r
      s   r
   c               @   s2   e Zd ZeZdd Zd
ddZdd Zdd	 ZdS )DefaultContentNegotiationc             C   s$   x|D ]}t |j|jr|S qW dS )z
        Given a list of parsers and a media type, return the appropriate
        parser to handle the incoming request.
        N)r   
media_typecontent_type)r   r   r   parserr   r   r   r      s    
z'DefaultContentNegotiation.select_parserNc             C   s   | j j}|p|jj|}|r(| j||}| j|}xt|D ]|}xv|D ]n}xh|D ]`}	t|j|	rPt	|	}
t	|jj
|
j
krdj|jftdd |
jj D  }||fS ||	fS qPW qFW q<W tj|ddS )zq
        Given a request and a list of renderers, return a two-tuple of:
        (renderer, media type).
        ;c             s   s$   | ]\}}d j ||jtV  qdS )z{0}={1}N)formatdecoder   ).0keyvaluer   r   r   	<genexpr>E   s   z<DefaultContentNegotiation.select_renderer.<locals>.<genexpr>)Zavailable_renderersN)settingsZURL_FORMAT_OVERRIDEZquery_paramsgetfilter_renderersget_accept_listr	   r   r   r   
precedencejointupleparamsitemsr   ZNotAcceptable)r   r   r   r   Zformat_query_paramr   ZacceptsZmedia_type_setrendererr   Zmedia_type_wrapperZfull_media_typer   r   r   r   %   s&    



z)DefaultContentNegotiation.select_rendererc                s    fdd|D }|st |S )z
        If there is a '.json' style format suffix, filter the renderers
        so that we only negotiation against those that accept that format.
        c                s   g | ]}|j  kr|qS r   )r   )r   r,   )r   r   r   
<listcomp>U   s    z>DefaultContentNegotiation.filter_renderers.<locals>.<listcomp>)r   )r   r   r   r   )r   r   r%   P   s    z*DefaultContentNegotiation.filter_renderersc             C   s"   |j jdd}dd |jdD S )zd
        Given the incoming request, return a tokenized list of media
        type strings.
        ZHTTP_ACCEPTz*/*c             S   s   g | ]}|j  qS r   )strip)r   tokenr   r   r   r-   a   s    z=DefaultContentNegotiation.get_accept_list.<locals>.<listcomp>,)ZMETAr$   split)r   r   headerr   r   r   r&   [   s    z)DefaultContentNegotiation.get_accept_list)N)	r   r   r   r   r#   r   r   r%   r&   r   r   r   r   r      s
   

+r   N)__doc__
__future__r   Zdjango.httpr   Zrest_frameworkr   r   Zrest_framework.settingsr   Zrest_framework.utils.mediatypesr   r   r	   objectr
   r   r   r   r   r   <module>   s   