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.
* owner: nobody => Sangwoon Yun
* status: new => assigned
--
Ticket URL: <https://code.djangoproject.com/ticket/34997#comment:1>
* status: assigned => closed
* resolution: => invalid
Comment:
Thanks for this ticket, however I'm not sure how `name` could work for
`path()` in `include()`. `name` and `app_name` are two different things,
if you want to define `app_name` when calling `include()` you should pass
a tuple, check out
[https://docs.djangoproject.com/en/stable/ref/urls/#django.urls.include
docs].
If you're having trouble understanding how it works, see
TicketClosingReasons/UseSupportChannels for ways to get help.
--
Ticket URL: <https://code.djangoproject.com/ticket/34997#comment:2>