3
Ah`                 @   sb   d 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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.
    )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-9m32_hle/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{}={}N)formatdecoder   ).0keyvaluer   r   r   	<genexpr>C   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>S   s    z>DefaultContentNegotiation.filter_renderers.<locals>.<listcomp>)r   )r   r   r   r   )r   r   r$   N   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,   _   s    z=DefaultContentNegotiation.get_accept_list.<locals>.<listcomp>,)ZMETAr#   split)r   r   headerr   r   r   r%   Y   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__Zdjango.httpr   Zrest_frameworkr   r   Zrest_framework.settingsr   Zrest_framework.utils.mediatypesr   r   r   r	   r   r   r   r   r   <module>   s   