#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.