a
    còfoI  ã                   @   sú   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 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.
é    )Ú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   ZViewSetÚsuffixú )ÚgetattrÚ	__class__Ú__name__r   Zremove_trailing_stringZcamelcase_to_spaces)Úviewr   r   © r   úQ/home/httpd/docs/test/DocsMgr/lib/python3.9/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
   Zmarkup_description)r   Úhtmlr   r   r   r   Úget_view_description/   s    
r#   c                  C   s,   t  ¡ D ]} | jd r| jr|  d¡ qd S )NZATOMIC_REQUESTST)r   ÚallZsettings_dictZin_atomic_blockÚset_rollback)Údbr   r   r   r%   A   s    r%   c                 C   sª   t | tƒrtj| jŽ } nt | tƒr.tj| jŽ } t | tjƒr¦i }t| ddƒrT| j|d< t| ddƒrnd| j	 |d< t | j
ttfƒr†| 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   ZNotFoundÚargsr   ZAPIExceptionr   r'   r(   r)   ÚlistÚdictr%   r   Ústatus_code)ÚexcÚcontextr*   Údatar   r   r   Úexception_handlerG   s     




r3   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,dGd+d,„Z-d-d.„ Z.d/d0„ Z/d1d2„ Z0d3d4„ Z1d5d6„ Z2d7d8„ Z3d9d:„ Z4d;d<„ Z5d=d>„ Z6d?d@„ Z7dAdB„ Z8dCdD„ Z9‡  Z:S )HÚAPIViewc                    sL   t t| ddƒtjjƒr&dd„ }|| j_tƒ jf i |¤Ž}| |_	||_
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ƒ‚d S )Nz�Do 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)r+   r   r   ÚqueryZQuerySetr5   Z
_fetch_allÚsuperÚas_viewÚclsÚ
initkwargsr   )r;   r<   r7   r   ©r   r   r   r:   y   s    zAPIView.as_viewc                 C   s   |   ¡ S )zZ
        Wrap Django's private `_allowed_methods` interface in a public property.
        )Z_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 )NZAllowz, é   ÚAcceptÚVary)Újoinr@   ÚlenÚrenderer_classes)r?   r*   r   r   r   Údefault_response_headers™   s
    ÿz APIView.default_response_headersc                 O   s   t  |j¡‚dS )z�
        If `request.method` does not correspond to a handler method,
        determine what kind of exception to raise.
        N)r   ZMethodNotAllowedÚmethod)r?   Úrequestr,   Úkwargsr   r   r   Úhttp_method_not_allowed¢   s    zAPIView.http_method_not_allowedNc                 C   s&   |j r|jst ¡ ‚tj||d�‚dS )zY
        If request is not permitted, determine what kind of exception to raise.
        )r)   ÚcodeN)ÚauthenticatorsZsuccessful_authenticatorr   ÚNotAuthenticatedr   )r?   rI   ÚmessagerL   r   r   r   Úpermission_denied©   s    zAPIView.permission_deniedc                 C   s   t  |¡‚dS )zU
        If request is throttled, determine what kind of exception to raise.
        N)r   Z	Throttled)r?   rI   r(   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_authenticatorsZauthenticate_header)r?   rI   rM   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.
        r,   r   rJ   )r   r,   rJ   ©r   )r?   Úhttp_requestr   r   r   Úget_parser_contextÀ   s    

ýzAPIView.get_parser_contextc                 C   s&   | 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.
        r,   r   rJ   rI   N©r   r,   rJ   rI   rT   r>   r   r   r   Úget_renderer_contextÍ   s
    


üzAPIView.get_renderer_contextc                 C   s&   | t | ddƒt | di ƒt | ddƒdœS )zp
        Returns a dict that is passed through to EXCEPTION_HANDLER,
        as the `context` argument.
        r,   r   rJ   rI   NrW   rT   r>   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   ZVIEW_NAME_FUNCTION)r?   Ú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   ZVIEW_DESCRIPTION_FUNCTION)r?   r"   rZ   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   ZFORMAT_SUFFIX_KWARGÚget)r?   rJ   r   r   r   Úget_format_suffixù   s    zAPIView.get_format_suffixc                 C   s   dd„ | j D ƒS )zX
        Instantiates and returns the list of renderers that this view can use.
        c                 S   s   g | ]
}|ƒ ‘qS r   r   )Ú.0Úrendererr   r   r   Ú
<listcomp>  ó    z)APIView.get_renderers.<locals>.<listcomp>)rF   r>   r   r   r   Úget_renderers   s    zAPIView.get_renderersc                 C   s   dd„ | j D ƒS )zV
        Instantiates and returns the list of parsers that this view can use.
        c                 S   s   g | ]
}|ƒ ‘qS r   r   )r]   Úparserr   r   r   r_   
  r`   z'APIView.get_parsers.<locals>.<listcomp>)Úparser_classesr>   r   r   r   Úget_parsers  s    zAPIView.get_parsersc                 C   s   dd„ | j D ƒS )z]
        Instantiates and returns the list of authenticators that this view can use.
        c                 S   s   g | ]
}|ƒ ‘qS r   r   )r]   Úauthr   r   r   r_     r`   z.APIView.get_authenticators.<locals>.<listcomp>)Úauthentication_classesr>   r   r   r   rR     s    zAPIView.get_authenticatorsc                 C   s   dd„ | j D ƒS )z[
        Instantiates and returns the list of permissions that this view requires.
        c                 S   s   g | ]
}|ƒ ‘qS r   r   )r]   Ú
permissionr   r   r   r_     r`   z+APIView.get_permissions.<locals>.<listcomp>)Úpermission_classesr>   r   r   r   Úget_permissions  s    zAPIView.get_permissionsc                 C   s   dd„ | j D ƒS )zU
        Instantiates and returns the list of throttles that this view uses.
        c                 S   s   g | ]
}|ƒ ‘qS r   r   )r]   Úthrottler   r   r   r_     r`   z)APIView.get_throttles.<locals>.<listcomp>)Úthrottle_classesr>   r   r   r   Úget_throttles  s    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_classrm   r>   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   ZEXCEPTION_HANDLERr>   r   r   r   Úget_exception_handler&  s    zAPIView.get_exception_handlerc                 C   sV   |   ¡ }|  ¡ }z| ||| j¡W S  tyP   |rJ|d |d jf Y S ‚ Y n0 dS )zU
        Determine which renderer and media type to use render the response.
        r   N)ra   ro   Zselect_rendererÚformat_kwargÚ	ExceptionÚ
media_type)r?   rI   ÚforceZ	renderersZconnegr   r   r   Úperform_content_negotiation.  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)r?   rI   r   r   r   Úperform_authentication<  s    zAPIView.perform_authenticationc                 C   s>   |   ¡ D ]0}| || ¡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.
        rO   NrL   ©rO   rL   )ri   Zhas_permissionrP   r   )r?   rI   rg   r   r   r   Úcheck_permissionsF  s    

ýzAPIView.check_permissionsc                 C   s@   |   ¡ D ]2}| || |¡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.
        rO   NrL   rx   )ri   Zhas_object_permissionrP   r   )r?   rI   Úobjrg   r   r   r   Úcheck_object_permissionsS  s    

ýz APIView.check_object_permissionsc                 C   sZ   g }|   ¡ D ]}| || ¡s| | ¡ ¡ q|rVdd„ |D ƒ}t|dd�}|  ||¡ 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   )r]   Údurationr   r   r   r_   m  s   ÿz+APIView.check_throttles.<locals>.<listcomp>N)Údefault)rl   Zallow_requestÚappendr(   ÚmaxrQ   )r?   rI   Zthrottle_durationsrj   Z	durationsr|   r   r   r   Úcheck_throttles`  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)r?   rI   r,   rJ   Úschemer   r   r   r‚   u  s    
zAPIView.determine_versionc                 O   s(   |   |¡}t||  ¡ |  ¡ |  ¡ |d�S )z5
        Returns the initial request object.
        )ÚparsersrM   Z
negotiatorÚparser_context)rV   r   rd   rR   ro   )r?   rI   r,   rJ   r…   r   r   r   Úinitialize_request�  s    
ûzAPIView.initialize_requestc                 O   st   | j f i |¤Ž| _|  |¡}|\|_|_| j|g|¢R i |¤Ž\}}|| |_|_|  |¡ |  	|¡ |  
|¡ dS )zX
        Runs anything that needs to occur prior to calling the method handler.
        N)r\   rq   ru   Úaccepted_rendererÚaccepted_media_typer‚   ÚversionZversioning_schemerw   ry   r€   )r?   rI   r,   rJ   Únegr‰   rƒ   r   r   r   Úinitial�  s    


zAPIView.initialc           	      O   sª   t |tƒsJ dt|ƒ ƒ‚t |tƒrdt|ddƒsJ| j|dd�}|\|_|_|j|_|j|_|  ¡ |_	| j
 dd¡}|durŠt|t |¡ƒ | j
 ¡ D ]\}}|||< q”|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)rt   rC   )r+   r   Útyper   r   ru   r‡   rˆ   rX   Zrenderer_contextr*   Úpopr	   r   ÚsplitÚitems)	r?   rI   Úresponser,   rJ   rŠ   Zvary_headersÚkeyÚvaluer   r   r   Úfinalize_response¢  s$    þÿ


zAPIView.finalize_responsec                 C   sh   t |tjtjfƒr2|  | 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)r+   r   rN   ZAuthenticationFailedrS   rI   r'   r   ZHTTP_403_FORBIDDENr/   rp   rY   Úraise_uncaught_exceptionÚ	exception)r?   r0   r'   r3   r1   r�   r   r   r   Úhandle_exceptionÀ  s    ÿ

zAPIView.handle_exceptionc                 C   s2   t jr*| j}t|jdƒ}|dv}| |¡ |‚d S )NÚformat)r"   ÚapiZadmin)r   ÚDEBUGrI   r   r‡   Zforce_plaintext_errors)r?   r0   rI   Zrenderer_formatZ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 rrt
| |j ¡ | jƒ}n| j}||g|¢R i |¤Ž}W n. ty¾ } z|  |¡}W Y d}~n
d}~0 0 | 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)r,   rJ   r†   rI   rG   r*   r‹   rH   ÚlowerZhttp_method_namesr   rK   rr   r–   r“   r�   )r?   rI   r,   rJ   Úhandlerr�   r0   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_classrK   Zdetermine_metadatar   r   ZHTTP_200_OK)r?   rI   r,   rJ   r2   r   r   r   Úoptions  s    
zAPIView.options)NN)F)F);r   Ú
__module__Ú__qualname__r   ZDEFAULT_RENDERER_CLASSESrF   ZDEFAULT_PARSER_CLASSESrc   ZDEFAULT_AUTHENTICATION_CLASSESrf   ZDEFAULT_THROTTLE_CLASSESrk   ZDEFAULT_PERMISSION_CLASSESrh   Z!DEFAULT_CONTENT_NEGOTIATION_CLASSrn   ZDEFAULT_METADATA_CLASSr�   ZDEFAULT_VERSIONING_CLASSr�   r   r   ZschemaÚclassmethodr:   Úpropertyr@   rG   rK   rP   rQ   rS   rV   rX   rY   r   r#   r\   ra   rd   rR   ri   rl   ro   rp   ru   rw   ry   r{   r€   r‚   r†   r‹   r“   r–   r”   rœ   rž   Ú__classcell__r   r   r=   r   r4   h   s\   


	



r4   N)F)'r    Zdjango.confr   Zdjango.core.exceptionsr   Z	django.dbr   r   Zdjango.httpr   Zdjango.http.responser   Zdjango.utils.cacher   r	   Zdjango.utils.encodingr
   Zdjango.views.decorators.csrfr   Zdjango.views.genericr   Zrest_frameworkr   r   Zrest_framework.requestr   Zrest_framework.responser   Zrest_framework.schemasr   Zrest_framework.settingsr   Zrest_framework.utilsr   r   r#   r%   r3   r4   r   r   r   r   Ú<module>   s(   
!