a
    CgL$                  	   @   s   d 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mZmZ dd	lmZ dd
lmZ dd Zdd ZG dd dZG dd deejZG dd deejZG dd dejejeZG dd dej ejej!ej"ejeZ#dS )a  
ViewSets are essentially just a type of class based view, that doesn't provide
any method handlers, such as `get()`, `post()`, etc... but instead has actions,
such as `list()`, `retrieve()`, `create()`, etc...

Actions are only bound to methods at the point of instantiating the views.

    user_list = UserViewSet.as_view({'get': 'list'})
    user_detail = UserViewSet.as_view({'get': 'retrieve'})

Typically, rather than instantiate views from viewsets directly, you'll
register the viewset with a router and let the URL conf be determined
automatically.

    router = DefaultRouter()
    router.register(r'users', UserViewSet, 'user')
    urlpatterns = router.urls
    )update_wrapper)
getmembers)VERSION)NoReverseMatch)classonlymethod)csrf_exempt)genericsmixinsviews)MethodMapper)reversec                 C   s   t | dot| jtS )Nmapping)hasattr
isinstancer   r   )attr r   V/var/www/lab.imftr.de/x/nb_venv/lib/python3.9/site-packages/rest_framework/viewsets.py_is_extra_action    s    r   c                 C   s    | j |ksJ dj| |d| S )NzExpected function (`{func.__name__}`) to match its attribute name (`{name}`). If using a decorator, ensure the inner function is decorated with `functools.wraps`, or that `{func.__name__}.__name__` is otherwise set to `{name}`.funcname)__name__formatr   r   r   r   _check_attr_name$   s    r   c                       sJ   e Zd ZdZedddZ fddZdd Zed	d
 Z	dd Z
  ZS )ViewSetMixinad  
    This is the magic.

    Overrides `.as_view()` so that it takes an `actions` keyword that performs
    the binding of HTTP methods to actions on the Resource.

    For example, to create a concrete view binding the 'GET' and 'POST' methods
    to the 'list' and 'create' actions...

    view = MyViewSet.as_view({'get': 'list', 'post': 'create'})
    Nc                    s   d_ d_d_d_d_ s*tdD ]<}|jv rNtd|jf t|s.tdj|f q.dv rdv rtdj  fdd	}t	|d
d t	|j
d
d |_|_ |_tdkrd|_t|S )z
        Because of the way class based views create a closure around the
        instantiated view, we need to totally reimplement `.as_view`,
        and slightly modify the view function that is created and returned.
        NzwThe `actions` argument must be provided when calling `.as_view()` on a ViewSet. For example `.as_view({'get': 'list'})`zUYou tried to pass in the %s method name as a keyword argument to %s(). Don't do that.z#%s() received an invalid keyword %rr   suffixzO%s() received both `name` and `suffix`, which are mutually exclusive arguments.c                    s   f i }d v r*d vr* d  d<  |_   D ]\}}t||}t||| q8| |_||_||_|j| g|R i |S )Ngethead)
action_mapitemsgetattrsetattrrequestargskwargsdispatch)r"   r#   r$   selfmethodactionhandleractionscls
initkwargsr   r   viewg   s    
z"ViewSetMixin.as_view.<locals>.viewr   )updated)assigned)      F)r   descriptionr   detailbasename	TypeErrorZhttp_method_namesr   r   r   r%   r,   r-   r+   DJANGO_VERSIONZlogin_requiredr   )r,   r+   r-   keyr.   r   r*   r   as_view:   s:    	


zViewSetMixin.as_viewc                    sF   t  j|g|R i |}|j }|dkr4d| _n| j|| _|S )z[
        Set the `.action` attribute on the view, depending on the request method.
        optionsmetadata)superinitialize_requestr'   lowerr(   r   r   )r&   r"   r#   r$   r'   	__class__r   r   r=      s    
zViewSetMixin.initialize_requestc                 O   s^   d| j |f }d}| jr*| jjr*| jjj}|r:|d | }|d| j t|g|R i |S )z>
        Reverse the action for the given `url_name`.
        %s-%sN:r"   )r5   r"   resolver_match	namespace
setdefaultr   )r&   url_namer#   r$   rD   r   r   r   reverse_action   s    
zViewSetMixin.reverse_actionc                 C   s   dd t | tD S )zP
        Get the methods that are marked as an extra ViewSet `@action`.
        c                 S   s   g | ]\}}t ||qS r   )r   ).0r   r'   r   r   r   
<listcomp>   s   z2ViewSetMixin.get_extra_actions.<locals>.<listcomp>)r   r   )r,   r   r   r   get_extra_actions   s    zViewSetMixin.get_extra_actionsc              	      s   i } j du r|S  fdd  D }|D ]z}zbd j|jf } jjj}|r\d||f }t| j j	 jd} j
f i |j	}||| < W q, ty   Y q,0 q,|S )z
        Build a map of {names: urls} for the extra actions.

        This method will noop if `detail` was not provided as a view initkwarg.
        Nc                    s   g | ]}|j  j kr|qS r   )r4   )rH   r(   r&   r   r   rI      s   z9ViewSetMixin.get_extra_action_url_map.<locals>.<listcomp>rA   z%s:%s)r"   )r4   rJ   r5   rF   r"   rC   rD   r   r#   r$   r@   Zget_view_namer   )r&   Zaction_urlsr+   r(   rF   rD   urlr.   r   rK   r   get_extra_action_url_map   s$    


z%ViewSetMixin.get_extra_action_url_map)N)r   
__module____qualname____doc__r   r9   r=   rG   classmethodrJ   rM   __classcell__r   r   r?   r   r   -   s   Y
r   c                   @   s   e Zd ZdZdS )ViewSetzI
    The base ViewSet class does not provide any actions by default.
    Nr   rN   rO   rP   r   r   r   r   rS      s   rS   c                   @   s   e Zd ZdZdS )GenericViewSetz
    The GenericViewSet class does not provide any actions by default,
    but does include the base set of generic view behavior, such as
    the `get_object` and `get_queryset` methods.
    NrT   r   r   r   r   rU      s   rU   c                   @   s   e Zd ZdZdS )ReadOnlyModelViewSetzL
    A viewset that provides default `list()` and `retrieve()` actions.
    NrT   r   r   r   r   rV      s   rV   c                   @   s   e Zd ZdZdS )ModelViewSetz
    A viewset that provides default `create()`, `retrieve()`, `update()`,
    `partial_update()`, `destroy()` and `list()` actions.
    NrT   r   r   r   r   rW      s   rW   N)$rP   	functoolsr   inspectr   Zdjangor   r7   Zdjango.urlsr   Zdjango.utils.decoratorsr   Zdjango.views.decorators.csrfr   Zrest_frameworkr   r	   r
   Zrest_framework.decoratorsr   Zrest_framework.reverser   r   r   r   ZAPIViewrS   ZGenericAPIViewrU   ZRetrieveModelMixinZListModelMixinrV   ZCreateModelMixinZUpdateModelMixinZDestroyModelMixinrW   r   r   r   r   <module>   s4   	 0		