#34997: The name argument is ignored when creating url path using the include()
function.
----------------------------------------+----------------------------
               Reporter:  Sangwoon Yun  |          Owner:  nobody
                   Type:  Bug           |         Status:  new
              Component:  Core (URLs)   |        Version:  4.2
               Severity:  Normal        |       Keywords:  ulrs, path
           Triage Stage:  Unreviewed    |      Has patch:  0
    Needs documentation:  0             |    Needs tests:  0
Patch needs improvement:  0             |  Easy pickings:  0
                  UI/UX:  0             |
----------------------------------------+----------------------------
 Let me briefly show you an example code that is ignored.

 Our situation is when we use rest_framework.

 {{{
 from django.urls import path, include
 from rest_framework.routers import DefaultRouter

 from testapp.views import TestView

 app_name = 'test_namespace'

 test_router = DefaultRouter(trailing_slash=False)
 test_router.register('test', TestView)

 urlpatterns = [
     path('', include(test_router.urls), name='test')
 ]
 }}}

 If we use `test` as the name argument for the `path()` function in
 `urls.py` as above, we expect to get a url `/test` return when we use the
 `reverse()` function.
 However, the name provision is ignored and returns the model name-based
 `url_name`, which is the default by the `register()` method in the code
 above.
 The results of confirming the above causes through reverse engineering are
 as follows.
 The code below is from lines 61 to 91 of `django.urls`' `conf.py` file.

 {{{
 def _path(route, view, kwargs=None, name=None, Pattern=None):
     from django.views import View

     if kwargs is not None and not isinstance(kwargs, dict):
         raise TypeError(
             f"kwargs argument must be a dict, but got
 {kwargs.__class__.__name__}."
         )
     if isinstance(view, (list, tuple)):
         # For include(...) processing.
         pattern = Pattern(route, is_endpoint=False)
         urlconf_module, app_name, namespace = view
         return URLResolver(
             pattern,
             urlconf_module,
             kwargs,
             app_name=app_name,
             namespace=namespace,
         )
     elif callable(view):
         pattern = Pattern(route, name=name, is_endpoint=True)
         return URLPattern(pattern, view, kwargs, name)
     elif isinstance(view, View):
         view_cls_name = view.__class__.__name__
         raise TypeError(
             f"view must be a callable, pass {view_cls_name}.as_view(), not
 "
             f"{view_cls_name}()."
         )
     else:
         raise TypeError(
             "view must be a callable or a list/tuple in the case of
 include()."
         )
 }}}

 `if isinstance(view, (list, tuple))` statement is a case when using the
 `include()` function.
 If you look at the code, `URLResolver`'s `app_name` argument simply uses
 the `app_name` from the `view` argument.
 It will ignore the name argument that can be used when invoking the
 `path()` function without any logic.
 Although my example code is DRF and not pure django, I think we need a
 procedure to check the name argument of the `path()` function declared at
 the end.

 This code can be resolved with a single line of modification.
 We can modify code on line 76 as below:

 from
 {{{
 app_name=app_name,
 }}}
 to
 {{{
 app_name=name if name else app_name,
 }}}

-- 
Ticket URL: <https://code.djangoproject.com/ticket/34997>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/0107018c14502e6f-d0417a10-f877-42c0-b34e-fc00be81be6a-000000%40eu-central-1.amazonses.com.

Reply via email to