
    Nwgc6                     2   d Z ddl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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 Zd Z G d d      Z G d de      Z G d dej<                        Z G d de      Z y)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)
namedtuple)ImproperlyConfigured)NoReverseMatchpathre_path)views)Response)reverse)SchemaGenerator)
SchemaView)api_settings)format_suffix_patternsRouteurlmappingnamedetail
initkwargsDynamicRouter   r   r   r   c                 F    | j                  dd      j                  dd      S )zK
    Double brackets in regex of url_path for escape string formatting
    {z{{}z}})replace)url_paths    M/var/www/horilla/myenv/lib/python3.12/site-packages/rest_framework/routers.pyescape_curly_bracketsr   "   s$     C&..sD99    c                 &    t        j                  |  S )zX
    Takes an iterable of iterables, returns a single iterable containing all items
    )	itertoolschain)list_of_listss    r   flattenr$   )   s     ??M**r   c                   <    e Zd Zd ZddZd Zd Zd Zed        Z	y)	
BaseRouterc                     g | _         y N)registryselfs    r   __init__zBaseRouter.__init__1   s	    r   Nc                     || j                  |      }| j                  |      rd| d| d}t        |      | j                  j	                  |||f       t        | d      r| `y y )NzRouter with basename "zG" is already registered. Please provide a unique basename for viewset ""_urls)get_default_basenameis_already_registeredr   r)   appendhasattrr/   )r+   prefixviewsetbasenamemsgs        r   registerzBaseRouter.register4   s|    009H%%h/+H: 6DDK9AOC&s++fgx89 4!
 "r   c                 @    t        fd| j                  D              S )z;
        Check if `basename` is already registered
        c              3   0   K   | ]  \  }}}|k(    y wr(    ).0_prefix_viewsetr6   new_basenames       r   	<genexpr>z3BaseRouter.is_already_registered.<locals>.<genexpr>G   s     ]0K88|+]s   )anyr)   )r+   r?   s    `r   r1   z BaseRouter.is_already_registeredC   s     ]t}}]]]r   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+   r5   s     r   r0   zBaseRouter.get_default_basenameI   s    
 ""KLLr   c                     t        d      )zO
        Return a list of URL patterns, given the registered viewsets.
        zget_urls must be overriddenrD   r*   s    r   get_urlszBaseRouter.get_urlsP   s     ""?@@r   c                 \    t        | d      s| j                         | _        | j                  S )Nr/   )r3   rG   r/   r*   s    r   urlszBaseRouter.urlsV   s#    tW%DJzzr   r(   )
__name__
__module____qualname__r,   r8   r1   r0   rG   propertyrI   r;   r   r   r&   r&   0   s2    ^MA  r   r&   c            
            e Zd Z eddddddddi	       ed
ddi        eddddddddddi	       edddi       gZd fd	Zd Zd Zd Z	d Z
ddZd Z x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updatepartial_updatedestroy)rR   putpatchdeletez{basename}-detailTInstancez.^{prefix}/{lookup}/{url_path}{trailing_slash}$c                 r   |rdnd| _         || _        |rd| _        d| _        t        | _        nzd| _        d| _        t        | _        g }| j                  D ]I  }|j                  }|d   dk(  r|d	d  }|d
   dk(  r|d d
 }|j                  |j                  |             K || _        t        | 1          y )N/ z5(?P<{lookup_prefix}{lookup_url_kwarg}>{lookup_value})z[^/.]+z2<{lookup_value}:{lookup_prefix}{lookup_url_kwarg}>strr   ^   $)r   )trailing_slash
_use_regex_base_pattern_default_value_patternr   	_url_confr   routesr   r2   _replacesuperr,   )r+   rf   use_regex_path_routesroute	url_param	__class__s         r   r,   zSimpleRouter.__init__   s    %3c(!XD*2D'$DN!UD*/D'!DNG >!II	Q<3& )!"IR=C' )#2Iu~~)~<=> "DKr   c                     t        |dd      }|J d       |j                  j                  j                  j	                         S )rC   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_metaobject_namelower)r+   r5   rt   s      r   r0   z!SimpleRouter.get_default_basename   sK    
 7J5# 	8 &8 	8# ~~##//5577r   c                 T   t        t        | j                  D cg c]-  }t        |t              s|j
                  j                         / c}            }|j                         }|D cg c]  }|j                  |v r|j                   }}|rd}t        |dj                  |      z        |D cg c]  }|j                  s| }}|D cg c]  }|j                  r| }	}g }
| j                  D ]  }t        |t              r0|j                  r$|
|D cg c]  }| j                  ||       c}z  }
Ct        |t              r0|j                  s$|
|	D cg c]  }| j                  ||       c}z  }
|
j                  |        |
S c c}w c c}w c c}w c c}w c c}w c c}w )z
        Augment `self.routes` with any dynamically generated routes.

        Returns a list of the Route namedtuple.
        zZCannot use the @action decorator on the following methods, as they are existing routes: %sz, )rP   r$   rk   
isinstancer   r   valuesget_extra_actionsrJ   r   joinr   r   _get_dynamic_router2   )r+   r5   rp   known_actionsextra_actionsactionnot_allowedr7   detail_actionslist_actionsrk   s              r   
get_routeszSimpleRouter.get_routes   s    W$++%rYcdikpYqemm&:&:&<%rst113 +8
 &-/ OO
 
 >C&sTYY{-C'CDD 0=NV&NN-:P6&--PP[[ 	%E%.5<<P^_f4225&A__E<0P\]f4225&A]]e$	% 5 &s
 OP
 `]s4   FF*!F2FFF FF F%c                 Z   |j                   j                         }|j                  |j                         t	        |j
                        }t        |j                  j                  d|      |j                  |j                  j                  d|j                        |j                  |      S )Nz
{url_path}z
{url_name}r   )r   copyrW   kwargsr   r   r   r   r   r   r   url_namer   )r+   rp   r   r   r   s        r   r   zSimpleRouter._get_dynamic_route   s    %%**,
&--((9		!!,9NN##L&//B<<!
 	
r   c                 ^    i }|j                         D ]  \  }}t        ||      s|||<    |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.
        )itemsr3   )r+   r5   
method_mapbound_methodsmethodr   s         r   get_method_mapzSimpleRouter.get_method_map   sA     (..0 	/NFFw'(.f%	/ r   c                     t        |dd      }t        |dd      xs |}d}| j                  st        |dd      }|t        |d| j                        }| j                  j	                  |||      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
        lookup_fieldpklookup_url_kwargNlookup_value_converterlookup_value_regex)lookup_prefixr   lookup_value)ru   rg   ri   rh   format)r+   r5   r   r   r   r   s         r   get_lookup_regexzSimpleRouter.get_lookup_regex   s     w="7,>EU"7,DdKL"7,@$B]B]^L!!(('-% ) 
 	
r   c           	         g }| j                   D ]5  \  }}}| j                  |      }| j                  |      }|D ]  }| j                  ||j                        }|s#|j
                  j                  ||| j                        }	|s0| j                  t        u r|	d   dk(  r|	dd }	n|	dd dk(  rd|	dd z   }	|j                  j                         }
|
j                  ||j                  d	        |j                  |fi |
}|j                  j                  |
      }|j!                  | j                  |	||             	 8 |S )zQ
        Use the registered viewsets to generate a list of URL patterns.
        )r4   lookuprf   r   r_   rc   N   z^/rb   )r6   r   r6   r   )r)   r   r   r   r   r   r   rf   rj   r   r   r   rW   r   as_viewr   r2   )r+   retr4   r5   r6   r   rk   rp   r   regexr   viewr   s                r   rG   zSimpleRouter.get_urls
  sc    )- %	C%FGX**73F__W-F !C --gu}}E 		((!!#'#6#6 )  ~~- 8s?$)!"IErd* #eABi"--224
!! (#ll# 
 'ww=*=zz((((;

4>>%D>ABC!C	%	CN 
r   )TT)r`   )rJ   rK   rL   r   r   rk   r,   r0   r   r   r   r   rG   __classcell__rr   s   @r   rO   rO   ]   s     	-  # &)		
 	8(		
 	6!)#	 % *-	
 	A(		
G)FV28"H


8-r   rO   c                   "    e Zd ZdZdZdZdZd Zy)APIRootViewz7
    The default basic root view for DefaultRouter
    TNc           
         i }|j                   j                  }| j                  j                         D ]2  \  }}|r|dz   |z   }	 t	        |||||j                  d            ||<   4 t        |      S # t        $ r Y Kw xY w)N:r   )argsr   requestr   )resolver_match	namespaceapi_root_dictr   r
   rR   r   r	   )r+   r   r   r   r   r   keyr   s           r   rR   zAPIRootView.getB  s    **44	!//557 	MC$s?X5
"!#!::h/C		 }	 " s   "A33	A?>A?)rJ   rK   rL   __doc___ignore_model_permissionsschemar   rR   r;   r   r   r   r   :  s     !%FMr   r   c                   P     e Zd ZdZdZdZdZdZeZe	Z
eZ fdZddZ fdZ x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                     d|v r|j                  d      | _        nt        t        j                        | _        t        |   |i | y )Nroot_renderers)popr   rP   r   DEFAULT_RENDERER_CLASSESrm   r,   )r+   r   r   rr   s      r   r,   zDefaultRouter.__init__e  sB    v%"(**-=">D"&|'L'L"MD$)&)r   c                     i }| j                   d   j                  }| j                  D ]  \  }}}|j                  |      ||<    | j                  j                  |      S )z+
        Return a basic root view.
        r   r   )r   )rk   r   r)   r   r   r   )r+   api_urlsr   	list_namer4   r5   r6   s          r   get_api_root_viewzDefaultRouter.get_api_root_viewl  sl     KKN''	)- 	H%FGX$-$4$4h$4$GM&!	H ''m'DDr   c                     t         |          }| j                  r;| j                  |      }t	        d|| j
                        }|j                  |       | 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   r`   r   )	rm   rG   include_root_viewr   r   root_view_namer2   include_format_suffixesr   )r+   rI   r   root_urlrr   s       r   rG   zDefaultRouter.get_urlsw  sf    
 w!!!))4)8DB4+>+>?HKK!'')$/Dr   r(   )rJ   rK   rL   r   r   r   r   default_schema_renderersr   r   APISchemaViewr   r,   r   rG   r   r   s   @r   r   r   X  sE     "N#KM%O*	E r   r   )!r   r!   collectionsr   django.core.exceptionsr   django.urlsr   r   r   rest_frameworkr   rest_framework.responser	   rest_framework.reverser
   rest_framework.schemasr   rest_framework.schemas.viewsr   rest_framework.settingsr   rest_framework.urlpatternsr   r   r   r   r$   r&   rO   APIViewr   r   r;   r   r   <module>r      s     " 7 5 5   , * 2 3 0 =7NO.*QR:+* *ZZ: Zz%-- <.L .r   