o
    cZh/                     @   s   d Z ddlZddlmZ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lmZ ddlmZ edg dZedg dZdd Zdd ZG dd dZG dd deZG dd dejZG dd deZ dS )a  
Routers provide a convenient and consistent way of automatically
determining the URL conf for your API.

They are used by simply instantiating a Router class, and then registering
all the required ViewSets with that router.

For example, you might have a `urls.py` that looks something like this:

    router = routers.DefaultRouter()
    router.register('users', UserViewSet, 'user')
    router.register('accounts', AccountViewSet, 'account')

    urlpatterns = router.urls
    N)OrderedDict
namedtuple)ImproperlyConfigured)NoReverseMatchre_path)views)Response)reverse)SchemaGenerator)
SchemaView)api_settings)format_suffix_patternsRouteurlmappingnamedetail
initkwargsDynamicRouter   r   r   r   c                 C   s   |  dd ddS )zK
    Double brackets in regex of url_path for escape string formatting
    {z{{}z}})replace)url_path r   M/var/www/html/lang_env/lib/python3.10/site-packages/rest_framework/routers.pyescape_curly_brackets"   s   r   c                 C   s
   t j|  S )zX
    Takes an iterable of iterables, returns a single iterable containing all items
    )	itertoolschain)Zlist_of_listsr   r   r   flatten)   s   
r    c                   @   s:   e Zd Zdd ZdddZdd Zdd	 Zed
d ZdS )
BaseRouterc                 C   s
   g | _ d S N)registryselfr   r   r   __init__1   s   
zBaseRouter.__init__Nc                 C   s:   |d u r	|  |}| j|||f t| dr| `d S d S N_urls)get_default_basenamer#   appendhasattrr(   )r%   prefixviewsetbasenamer   r   r   register4   s   

zBaseRouter.registerc                 C      t d)q
        If `basename` is not specified, attempt to automatically determine
        it from the viewset.
        z'get_default_basename must be overriddenNotImplementedError)r%   r-   r   r   r   r)   =   s   zBaseRouter.get_default_basenamec                 C   r0   )zO
        Return a list of URL patterns, given the registered viewsets.
        zget_urls must be overriddenr2   r$   r   r   r   get_urlsD   s   zBaseRouter.get_urlsc                 C   s   t | ds
|  | _| jS r'   )r+   r4   r(   r$   r   r   r   urlsJ   s   

zBaseRouter.urlsr"   )	__name__
__module____qualname__r&   r/   r)   r4   propertyr5   r   r   r   r   r!   0   s    
	r!   c                	       s   e Zd Zeddddddddid	ed
ddi deddddddddddid	edddi dgZd& fdd	Zdd Zdd Zdd Z	dd  Z
d'd"d#Zd$d% Z  ZS )(SimpleRouterz^{prefix}{trailing_slash}$listcreate)getpostz{basename}-listFsuffixListr   z%^{prefix}/{url_path}{trailing_slash}$z{basename}-{url_name}r   z#^{prefix}/{lookup}{trailing_slash}$retrieveupdateZpartial_updatedestroy)r=   putpatchdeletez{basename}-detailTInstancez.^{prefix}/{lookup}/{url_path}{trailing_slash}$c                    s   |rdnd| _ t   d S )N/ )trailing_slashsuperr&   )r%   rJ   	__class__r   r   r&   ~   s   zSimpleRouter.__init__c                 C   s*   t |dd}|dusJ d|jjj S )r1   querysetNz`basename` argument not specified, and could not automatically determine the name from the viewset, as it does not have a `.queryset` attribute.)getattrmodel_metaZobject_namelower)r%   r-   rN   r   r   r   r)      s   z!SimpleRouter.get_default_basenamec                    s   t tdd jD  | } fdd|D }|r&d}t|d| dd |D }dd |D }g }jD ]1ttrPjrP|fdd|D 7 }q9ttrejse|fd	d|D 7 }q9|	 q9|S )
z
        Augment `self.routes` with any dynamically generated routes.

        Returns a list of the Route namedtuple.
        c                 S   s    g | ]}t |tr|j qS r   )
isinstancer   r   values).0router   r   r   
<listcomp>   s     z+SimpleRouter.get_routes.<locals>.<listcomp>c                    s   g | ]
}|j  v r|j qS r   )r6   rU   action)known_actionsr   r   rW      s
    
zZCannot use the @action decorator on the following methods, as they are existing routes: %sz, c                 S   s   g | ]}|j r|qS r   r   rX   r   r   r   rW          c                 S   s   g | ]}|j s|qS r   r[   rX   r   r   r   rW      r\   c                       g | ]}  |qS r   _get_dynamic_routerX   rV   r%   r   r   rW          c                    r]   r   r^   rX   r`   r   r   rW      ra   )
r;   r    routesZget_extra_actionsr   joinrS   r   r   r*   )r%   r-   Zextra_actionsnot_allowedmsgZdetail_actionsZlist_actionsrb   r   )rZ   rV   r%   r   
get_routes   s$   

zSimpleRouter.get_routesc                 C   sL   |j  }||j t|j}t|jd||j	|j
d|j|j|dS )Nz
{url_path}z
{url_name}r   )r   copyrB   kwargsr   r   r   r   r   r   r   url_namer   )r%   rV   rY   r   r   r   r   r   r_      s   

zSimpleRouter._get_dynamic_routec                 C   s,   i }|  D ]\}}t||r|||< q|S )z
        Given a viewset, and a mapping of http methods to actions,
        return a new mapping which only includes any mappings that
        are actually implemented by the viewset.
        )itemsr+   )r%   r-   Z
method_mapZbound_methodsmethodrY   r   r   r   get_method_map   s   
zSimpleRouter.get_method_maprI   c                 C   s<   d}t |dd}t |ddp|}t |dd}|j|||dS )	a  
        Given a viewset, return the portion of URL regex that is used
        to match against a single instance.

        Note that lookup_prefix is not used directly inside REST rest_framework
        itself, but is required in order to nicely support nested router
        implementations, such as drf-nested-routers.

        https://github.com/alanjds/drf-nested-routers
        z5(?P<{lookup_prefix}{lookup_url_kwarg}>{lookup_value})lookup_fieldpklookup_url_kwargNZlookup_value_regexz[^/.]+)lookup_prefixro   lookup_value)rO   format)r%   r-   rp   Z
base_regexrm   ro   rq   r   r   r   get_lookup_regex   s   zSimpleRouter.get_lookup_regexc              	   C   s   g }| j D ]b\}}}| |}| |}|D ]P}| ||j}|s"q|jj||| jd}	|s>|	dd dkr>d|	dd  }	|j	 }
|

||jd |j|fi |
}|jj|d}|t|	||d qq|S )	zQ
        Use the registered viewsets to generate a list of URL patterns.
        )r,   lookuprJ   N   z^/^)r.   r   r.   r   )r#   rs   rf   rl   r   r   rr   rJ   r   rg   rB   r   as_viewr   r*   r   )r%   retr,   r-   r.   rt   rb   rV   r   regexr   viewr   r   r   r   r4      s2   



zSimpleRouter.get_urls)T)rI   )r6   r7   r8   r   r   rb   r&   r)   rf   r_   rl   rs   r4   __classcell__r   r   rL   r   r:   Q   sR    +$
r:   c                   @   s$   e Zd ZdZdZdZdZdd ZdS )APIRootViewz7
    The default basic root view for DefaultRouter
    TNc              	   O   sl   t  }|jj}| j D ]%\}}|r|d | }zt|||||dd||< W q ty1   Y qw t|S )N:rr   )argsrh   requestrr   )	r   Zresolver_match	namespaceapi_root_dictrj   r	   r=   r   r   )r%   r   r   rh   rz   r   keyri   r   r   r   r=     s"   zAPIRootView.get)r6   r7   r8   __doc__Z_ignore_model_permissionsZschemar   r=   r   r   r   r   r~     s    r~   c                       sR   e Zd ZdZdZdZdZdZeZe	Z
eZ fddZdddZ fd	d
Z  ZS )DefaultRouterz
    The default router extends the SimpleRouter, but also adds in a default
    API root view, and adds format suffix patterns to the URLs.
    Tzapi-rootNc                    s8   d|v r| d| _nttj| _t j|i | d S )Nroot_renderers)popr   r;   r   ZDEFAULT_RENDERER_CLASSESrK   r&   )r%   r   rh   rL   r   r   r&   ;  s   zDefaultRouter.__init__c                 C   sB   t  }| jd j}| jD ]\}}}|j|d||< q| jj|dS )z+
        Return a basic root view.
        r   rw   )r   )r   rb   r   r#   rr   r~   ry   )r%   api_urlsr   Z	list_namer,   r-   r.   r   r   r   get_api_root_viewB  s
   zDefaultRouter.get_api_root_viewc                    sH   t   }| jr| j|d}td|| jd}|| | jr"t|}|S )z
        Generate the list of URL patterns, including a default root view
        for the API, and appending `.json` style format suffixes.
        )r   z^$rx   )	rK   r4   include_root_viewr   r   root_view_namer*   include_format_suffixesr   )r%   r5   r|   Zroot_urlrL   r   r   r4   M  s   

zDefaultRouter.get_urlsr"   )r6   r7   r8   r   r   r   r   Zdefault_schema_renderersr~   r   ZAPISchemaViewr
   r&   r   r4   r}   r   r   rL   r   r   .  s    
r   )!r   r   collectionsr   r   Zdjango.core.exceptionsr   Zdjango.urlsr   r   Zrest_frameworkr   Zrest_framework.responser   Zrest_framework.reverser	   Zrest_framework.schemasr
   Zrest_framework.schemas.viewsr   Zrest_framework.settingsr   Zrest_framework.urlpatternsr   r   r   r   r    r!   r:   ZAPIViewr~   r   r   r   r   r   <module>   s*    ! @