I'm writing reusable app. And I want to deploy it several times.
Here is urls.py:
urlpatterns = patterns('',
(r'^carphotos/', include('webui.photos.urls', app_name='car-photos') ),
(r'^userphotos/', include('webui.photos.urls', app_name='profile-photos') ),)
and photos/urls.py:
urlpatterns = patterns('webui.photos.views',
url(r'^$', album_list, name="album-list" )
url(r'^newalbum/$', album_page, {'create': True}, name="album-create"),)
On the album_list view I want to show url for creating new album album_page.
I found that I have to use parameter current_app of reverse function to get proper URL.
But how to get this current_app? I thought the answer is something simple. But I can't find it in django documentation.
Thanks, Nick
I know this is a pretty old question... but I think I found a solution:
As Will Hardy suggested you'll have to keep app_name
the same for both instances (or not define it at all, it will default to the app the included urls reside in). Define a separate namespace for each app instance though:
urlpatterns = patterns('',
(r'^carphotos/', include('webui.photos.urls', app_name="webui_photos", namespace='car-photos') ),
(r'^userphotos/', include('webui.photos.urls', app_name="webui_photos", namespace='profile-photos') ),
)
Now comes the slightly tricky part of setting the currently active app instance (namespace) in your views. Meaning you have to find out which app instance is active and pass it to RequestContext
.
To find the currently active app, django.urls.resolve
can be used:
r = resolve(request.path)
r.app_name # the app name
r.namespace # the the currently active instance
So you'll have to update your views (this assumes using the class based views) accordingly:
from django.urls import resolve
from django.views.generic import TemplateView
class AlbumCreateView(TemplateView):
template_name = 'path/to/my/template.html'
def render_to_response(self, context, **response_kwargs):
response_kwargs['current_app'] = resolve(self.request.path).namespace
return super(AlbumPageView, self).render_to_response(context, **response_kwargs)
Now the url tag will automatically reverse to the correct namespace and still allow reversing to a specific app namespace if needed:
{% url webui_photos:album-create %} {# returns the url for whatever app is current #}
{% url car-photos:album-create %}
{% url profile-photos:album-create %}
To reverse urls in views, the current app instance has to be passed in manually:
reverse('webui_photos:album-create', current_app=resolve(self.request.path).namespace))
In your urls, you have a different app_name
even though it's the same app. Set the app_name
to the same thing, and set namespace
uniquely for each instance. eg.
urlpatterns = patterns('',
(r'^carphotos/', include('webui.photos.urls', app_name="webui_photos", namespace='car-photos') ),
(r'^userphotos/', include('webui.photos.urls', app_name="webui_photos", namespace='profile-photos') ),)
Then provide the current_app
argument when using reverse. See http://docs.djangoproject.com/en/dev/topics/http/urls/#reverse and http://docs.djangoproject.com/en/dev/topics/http/urls/#url-namespaces
[edit] after re-reading your question:
you don't need to provide the current_app
argument if you are using the {% url %}
tag. As far as I'm lead to believe, it will automatically access a template variable called current_app
, which is automatically set based on the matched url.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With