o
    "7hJ                     @   s  d Z ddlm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 ddlmZmZ dd	lm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 ddlm Z  ddl!m"Z" ddl#m$Z$ dd Z%dddZ&dd Z'dd Z(G dd deZ)dS )zL
Provides an APIView class that is the base of all views in REST framework.
    )VERSION)settings)PermissionDenied)connectionsmodels)Http404)HttpResponseBase)cc_delim_repatch_vary_headers)	smart_str)csrf_exempt)View)
exceptionsstatus)Request)Response)DefaultSchema)api_settings)
formattingc                 C   sb   t | dd}|dur|S | jj}t|d}t|d}t|}t | dd}|r/|d| 7 }|S )z
    Given a view instance, return a textual name to represent the view.
    This name is used in the browsable API, and in OPTIONS responses.

    This function is the default for the `VIEW_NAME_FUNCTION` setting.
    nameNr   ViewSetsuffix )getattr	__class____name__r   remove_trailing_stringcamelcase_to_spaces)viewr   r    r   i/var/www/epreuve.sigeris.cm/public_html/epreuve/venv/lib/python3.10/site-packages/rest_framework/views.pyget_view_name   s   
r!   Fc                 C   s@   t | dd}|du r| jjpd}tt|}|rt|S |S )z
    Given a view instance, return a textual description to represent the view.
    This name is used in the browsable API, and in OPTIONS responses.

    This function is the default for the `VIEW_DESCRIPTION_FUNCTION` setting.
    descriptionN )r   r   __doc__r   dedentr   markup_description)r   htmlr"   r   r   r    get_view_description0   s   
r(   c                  C   s,   t  D ]} | jd r| jr| d qd S )NATOMIC_REQUESTST)r   allsettings_dictin_atomic_blockset_rollback)dbr   r   r    r-   B   s
   
r-   c                 C   s   t | trtj| j } nt | trtj| j } t | tjrSi }t| ddr*| j|d< t| ddr7d| j	 |d< t | j
ttfrC| j
}nd| j
i}t  t|| j|dS dS )	a4  
    Returns the response that should be used for any given exception.

    By default we handle the REST framework `APIException`, and also
    Django's built-in `Http404` and `PermissionDenied` exceptions.

    Any unhandled exceptions may return `None`, which will cause a 500 error
    to be raised.
    auth_headerNzWWW-Authenticatewaitz%dzRetry-Afterdetail)r   headers)
isinstancer   r   NotFoundargsr   APIExceptionr   r/   r0   r1   listdictr-   r   status_code)exccontextr2   datar   r   r    exception_handlerH   s    




r=   c                       sh  e Zd ZejZejZejZ	ej
ZejZejZejZejZeZe Ze fddZedd Zedd Zdd ZdEd
dZdd Zdd Zdd Z dd Z!dd Z"dd Z#dFddZ$dd Z%dd Z&dd  Z'd!d" Z(d#d$ Z)d%d& Z*d'd( Z+d)d* Z,dFd+d,Z-d-d. Z.d/d0 Z/d1d2 Z0d3d4 Z1d5d6 Z2d7d8 Z3d9d: Z4d;d< Z5d=d> Z6d?d@ Z7dAdB Z8dCdD Z9  Z:S )GAPIViewc                    sZ   t t| ddtjjrdd }|| j_t jdi |}| |_	||_
tdkr)d|_t|S )z
        Store the original class on the view function.

        This allows us to discover information about the view when we do URL
        reverse lookups.  Used for breadcrumb generation.
        querysetNc                   S   s   t d)NzDo not evaluate the `.queryset` attribute directly, as the result will be cached and reused between requests. Use `.all()` or call `.get_queryset()` instead.)RuntimeErrorr   r   r   r    force_evaluation   s   z)APIView.as_view.<locals>.force_evaluation)      Fr   )r3   r   r   queryQuerySetr?   
_fetch_allsuperas_viewcls
initkwargsDJANGO_VERSIONlogin_requiredr   )rI   rJ   rA   r   r   r   r    rH   z   s   zAPIView.as_viewc                 C   s   |   S )zZ
        Wrap Django's private `_allowed_methods` interface in a public property.
        )_allowed_methodsselfr   r   r    allowed_methods   s   zAPIView.allowed_methodsc                 C   s*   dd | ji}t| jdkrd|d< |S )NAllowz, rC   AcceptVary)joinrQ   lenrenderer_classes)rP   r2   r   r   r    default_response_headers   s
   z APIView.default_response_headersc                 O   s   t |j)z
        If `request.method` does not correspond to a handler method,
        determine what kind of exception to raise.
        )r   MethodNotAllowedmethod)rP   requestr5   kwargsr   r   r    http_method_not_allowed   s   zAPIView.http_method_not_allowedNc                 C   s"   |j r
|js
t tj||d)zY
        If request is not permitted, determine what kind of exception to raise.
        )r1   code)authenticatorssuccessful_authenticatorr   NotAuthenticatedr   )rP   r[   messager^   r   r   r    permission_denied   s   zAPIView.permission_deniedc                 C   s
   t |)zU
        If request is throttled, determine what kind of exception to raise.
        )r   	Throttled)rP   r[   r0   r   r   r    	throttled   s   
zAPIView.throttledc                 C   s   |   }|r|d |S dS )z
        If a request is unauthenticated, determine the WWW-Authenticate
        header to use for 401 responses, if any.
        r   N)get_authenticatorsauthenticate_header)rP   r[   r_   r   r   r    get_authenticate_header   s   zAPIView.get_authenticate_headerc                 C   s   | t | ddt | di dS )z|
        Returns a dict that is passed through to Parser.parse(),
        as the `parser_context` keyword argument.
        r5   r   r\   )r   r5   r\   r   )rP   http_requestr   r   r    get_parser_context   s   

zAPIView.get_parser_contextc                 C   &   | t | ddt | di t | dddS )z
        Returns a dict that is passed through to Renderer.render(),
        as the `renderer_context` keyword argument.
        r5   r   r\   r[   Nr   r5   r\   r[   ri   rO   r   r   r    get_renderer_context   s
   


zAPIView.get_renderer_contextc                 C   rl   )zp
        Returns a dict that is passed through to EXCEPTION_HANDLER,
        as the `context` argument.
        r5   r   r\   r[   Nrm   ri   rO   r   r   r    get_exception_handler_context   s
   


z%APIView.get_exception_handler_contextc                 C   s   | j j}|| S )zf
        Return the view name, as used in OPTIONS responses and in the
        browsable API.
        )r   VIEW_NAME_FUNCTION)rP   funcr   r   r    r!      s   zAPIView.get_view_nameFc                 C   s   | j j}|| |S )z{
        Return some descriptive text for the view, as used in OPTIONS responses
        and in the browsable API.
        )r   VIEW_DESCRIPTION_FUNCTION)rP   r'   rq   r   r   r    r(      s   
zAPIView.get_view_descriptionc                 K   s   | j jr|| j jS dS )zQ
        Determine if the request includes a '.json' style format suffix
        N)r   FORMAT_SUFFIX_KWARGget)rP   r\   r   r   r    get_format_suffix   s   zAPIView.get_format_suffixc                 C      dd | j D S )zX
        Instantiates and returns the list of renderers that this view can use.
        c                 S      g | ]}| qS r   r   ).0rendererr   r   r    
<listcomp>
      z)APIView.get_renderers.<locals>.<listcomp>)rW   rO   r   r   r    get_renderers     zAPIView.get_renderersc                 C   rv   )zV
        Instantiates and returns the list of parsers that this view can use.
        c                 S   rw   r   r   )rx   parserr   r   r    rz     r{   z'APIView.get_parsers.<locals>.<listcomp>)parser_classesrO   r   r   r    get_parsers  r}   zAPIView.get_parsersc                 C   rv   )z]
        Instantiates and returns the list of authenticators that this view can use.
        c                 S   rw   r   r   )rx   authr   r   r    rz     r{   z.APIView.get_authenticators.<locals>.<listcomp>)authentication_classesrO   r   r   r    rf     r}   zAPIView.get_authenticatorsc                 C   rv   )z[
        Instantiates and returns the list of permissions that this view requires.
        c                 S   rw   r   r   )rx   
permissionr   r   r    rz     r{   z+APIView.get_permissions.<locals>.<listcomp>)permission_classesrO   r   r   r    get_permissions  r}   zAPIView.get_permissionsc                 C   rv   )zU
        Instantiates and returns the list of throttles that this view uses.
        c                 S   rw   r   r   )rx   throttler   r   r    rz   "  r{   z)APIView.get_throttles.<locals>.<listcomp>)throttle_classesrO   r   r   r    get_throttles  r}   zAPIView.get_throttlesc                 C   s   t | dds|  | _| jS )zN
        Instantiate and return the content negotiation class to use.
        _negotiatorN)r   content_negotiation_classr   rO   r   r   r    get_content_negotiator$  s   
zAPIView.get_content_negotiatorc                 C   s   | j jS )zD
        Returns the exception handler that this view uses.
        )r   EXCEPTION_HANDLERrO   r   r   r    get_exception_handler,  s   zAPIView.get_exception_handlerc                 C   sN   |   }|  }z	|||| jW S  ty&   |r%|d |d jf Y S  w )zU
        Determine which renderer and media type to use render the response.
        r   )r|   r   select_rendererformat_kwarg	Exception
media_type)rP   r[   force	renderersconnegr   r   r    perform_content_negotiation4  s   z#APIView.perform_content_negotiationc                 C   s
   |j  dS )a  
        Perform authentication on the incoming request.

        Note that if you override this and simply 'pass', then authentication
        will instead be performed lazily, the first time either
        `request.user` or `request.auth` is accessed.
        N)user)rP   r[   r   r   r    perform_authenticationB  s   
zAPIView.perform_authenticationc                 C   s>   |   D ]}||| s| j|t|ddt|ddd qdS )z
        Check if the request should be permitted.
        Raises an appropriate exception if the request is not permitted.
        rb   Nr^   rb   r^   )r   has_permissionrc   r   )rP   r[   r   r   r   r    check_permissionsL  s   

zAPIView.check_permissionsc                 C   s@   |   D ]}||| |s| j|t|ddt|ddd qdS )z
        Check if the request should be permitted for a given object.
        Raises an appropriate exception if the request is not permitted.
        rb   Nr^   r   )r   has_object_permissionrc   r   )rP   r[   objr   r   r   r    check_object_permissionsY  s   

z APIView.check_object_permissionsc                 C   s^   g }|   D ]}||| s||  q|r-dd |D }t|dd}| || dS dS )z|
        Check if request should be throttled.
        Raises an appropriate exception if the request is throttled.
        c                 S   s   g | ]}|d ur|qS )Nr   )rx   durationr   r   r    rz   s  s
    z+APIView.check_throttles.<locals>.<listcomp>N)default)r   allow_requestappendr0   maxre   )rP   r[   throttle_durationsr   	durationsr   r   r   r    check_throttlesf  s   zAPIView.check_throttlesc                 O   s2   | j du rdS |   }|j|g|R i ||fS )z
        If versioning is being used, then determine any API version for the
        incoming request. Returns a two-tuple of (version, versioning_scheme)
        NNN)versioning_classdetermine_version)rP   r[   r5   r\   schemer   r   r    r   {  s   
zAPIView.determine_versionc                 O   s(   |  |}t||  |  |  |dS )z5
        Returns the initial request object.
        )parsersr_   
negotiatorparser_context)rk   r   r   rf   r   )rP   r[   r5   r\   r   r   r   r    initialize_request  s   
zAPIView.initialize_requestc                 O   st   | j di || _| |}|\|_|_| j|g|R i |\}}|||_|_| | | 	| | 
| dS )zX
        Runs anything that needs to occur prior to calling the method handler.
        Nr   )ru   r   r   accepted_rendereraccepted_media_typer   versionversioning_schemer   r   r   )rP   r[   r5   r\   negr   r   r   r   r    initial  s   


zAPIView.initialc           	      O   s   t |tsJ dt| t |tr2t|dds%| j|dd}|\|_|_|j|_|j|_|  |_	| j
dd}|durEt|t| | j
 D ]\}}|||< qJ|S )z4
        Returns the final response object.
        zrExpected a `Response`, `HttpResponse` or `StreamingHttpResponse` to be returned from the view, but received a `%s`r   NT)r   rT   )r3   r   typer   r   r   r   r   rn   renderer_contextr2   popr
   r	   splititems)	rP   r[   responser5   r\   r   vary_headerskeyvaluer   r   r    finalize_response  s$   


zAPIView.finalize_responsec                 C   sh   t |tjtjfr| | j}|r||_ntj|_	| 
 }|  }|||}|du r/| | d|_|S )zz
        Handle any exception that occurs, by returning an appropriate response,
        or re-raising the error.
        NT)r3   r   ra   AuthenticationFailedrh   r[   r/   r   HTTP_403_FORBIDDENr9   r   ro   raise_uncaught_exception	exception)rP   r:   r/   r=   r;   r   r   r   r    handle_exception  s   

zAPIView.handle_exceptionc                 C   s.   t jr| j}t|jd}|dv}|| |)Nformat)r'   apiadmin)r   DEBUGr[   r   r   force_plaintext_errors)rP   r:   r[   renderer_formatuse_plaintext_tracebackr   r   r    r     s   
z APIView.raise_uncaught_exceptionc              
   O   s   || _ || _| j|g|R i |}|| _| j| _z/| j|g|R i | |j | j	v r9t
| |j | j}n| j}||g|R i |}W n ty_ } z| |}W Y d}~nd}~ww | j||g|R i || _| jS )z
        `.dispatch()` is pretty much the same as Django's regular dispatch,
        but with extra hooks for startup, finalize, and exception handling.
        N)r5   r\   r   r[   rX   r2   r   rZ   lowerhttp_method_namesr   r]   r   r   r   r   )rP   r[   r5   r\   handlerr   r:   r   r   r    dispatch  s&   zAPIView.dispatchc                 O   s@   | j du r| j|g|R i |S |   || }t|tjdS )z<
        Handler method for HTTP 'OPTIONS' request.
        N)r   )metadata_classr]   determine_metadatar   r   HTTP_200_OK)rP   r[   r5   r\   r<   r   r   r    options  s   
zAPIView.optionsr   F);r   
__module____qualname__r   DEFAULT_RENDERER_CLASSESrW   DEFAULT_PARSER_CLASSESr   DEFAULT_AUTHENTICATION_CLASSESr   DEFAULT_THROTTLE_CLASSESr   DEFAULT_PERMISSION_CLASSESr   !DEFAULT_CONTENT_NEGOTIATION_CLASSr   DEFAULT_METADATA_CLASSr   DEFAULT_VERSIONING_CLASSr   r   r   schemaclassmethodrH   propertyrQ   rX   r]   rc   re   rh   rk   rn   ro   r!   r(   ru   r|   r   rf   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   __classcell__r   r   rM   r    r>   i   s^    


	



r>   Nr   )*r$   djangor   rK   django.confr   django.core.exceptionsr   	django.dbr   r   django.httpr   django.http.responser   django.utils.cacher	   r
   django.utils.encodingr   django.views.decorators.csrfr   django.views.genericr   rest_frameworkr   r   rest_framework.requestr   rest_framework.responser   rest_framework.schemasr   rest_framework.settingsr   rest_framework.utilsr   r!   r(   r-   r=   r>   r   r   r   r    <module>   s,    
!