Opened 13 months ago
Closed 13 months ago
#34997 closed Bug (invalid)
The name argument is ignored when creating url path using the include() function.
Reported by: | Sangwoon Yun | Owned by: | Sangwoon Yun |
---|---|---|---|
Component: | Core (URLs) | Version: | 4.2 |
Severity: | Normal | Keywords: | ulrs, path |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
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,
Change History (2)
comment:1 by , 13 months ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:2 by , 13 months ago
Resolution: | → invalid |
---|---|
Status: | assigned → closed |
Thanks for this ticket, however I'm not sure how
name
could work forpath()
ininclude()
.name
andapp_name
are two different things, if you want to defineapp_name
when callinginclude()
you should pass a tuple, check out docs.If you're having trouble understanding how it works, see TicketClosingReasons/UseSupportChannels for ways to get help.