Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
323 views
in Technique[技术] by (71.8m points)

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

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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))

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...