Reputation: 1213
I have been struggling with reversing URLs with a reusable Django app. Here's the basic layout of my problem.
Reusable App:
In the urls.py
file it has the following pattern:
url(r'^object-list/$', ObjectListView.as_view(), name='object-list')
Somewhere in the reusable app's views.py
, there is the following reverse call:
reverse('object-list')
My Project:
In the project where I want to use this app, I have another conflicting view name, so I namespace the app's URLs like so:
url(r'^app-stuff/', include('app.urls', namespace='app'))
The Problem:
This has the consequence of causing all reverse calls within the app to throw a NoReverseMatch
exception when it tries to lookup object-detail
, because the URL now has the name app:object-detail
.
I have access to the app in question, so I can modify the calls it makes to reverse
, but I would like to do it in a way that doesn't involve hardcoding a namespace. I have read the documentation on the current_app
and namespace
arguments to the include
function but I don't quite understand if they would help solve the issue I'm having.
Any suggestions you might have are greatly appreciated.
Upvotes: 1
Views: 837
Reputation: 1213
I solved this after reading Django's docs on URL resolution more closely.
If you have a reusable app called myapp
, you can add the property app_name
to its URL configuration to give it an application namespace. Example:
# myapp/urls.py
app_name = 'myapp'
urlpatterns = [
url(r'^index/$', IndexView.as_view(), name='index')
]
Now, even if the app's URLs are included like so:
# project/urls.py
urlpatterns = [
url(r'^myapp/', include('myapp.urls', namespace='random-namespace')),
]
...the urls are still accessible using reverse('myapp:index')
.
If you would like to see this in more detail, I created a small GitHub repo with an example.
Edit:
Specifying the app_name
property in urls.py
only works on Django 1.9 and up. For Django 1.8, you have to use the app_name
parameter in the include()
function.
Upvotes: 3