How to get current_app for using with reverse in multi-deployable reusable Django application?

眉间皱痕 提交于 2019-11-27 11:48:45

问题


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


回答1:


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.core.urlresolvers.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.core.urlresolvers 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))



回答2:


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.




回答3:


After exploring this topic for several days, I found that it isn't natural to mount django app more than once.

There is implementation of pluggable applications pattern: http://github.com/nowells/django-pluggables. It looks too tricky for me.

So I decided to move repeated functionality to custom tags and duplicate templates for each usage of my app. I hope using custom tags and extend feature help me to follow DRY principle.




回答4:


I believe that's what the sites framework is for.



来源:https://stackoverflow.com/questions/2030225/how-to-get-current-app-for-using-with-reverse-in-multi-deployable-reusable-djang

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!