也许简单的问题,我只是失去了一些东西,但我坚持的想法。
我有几个服务站点,不同的Django项目sessions.py
和完全不同的ROOT_URLCONF
秒。 一个网站处理用户注册,认证和配置文件设置,其他网站(另一个域)作为文件管理器等。 站点共享同一数据库,媒体和模板。 所有网站都共享相同的用户群,实现某种透明的单点登录/单点登录关闭装置。 它就像一个大工地,跨多个域跨越。
问题是,我有很多的{% url %}
在我的模板标签,当模板的其他网站上使用他们不工作。 我想,以避免硬编码的URL尽可能。
例如,在站点A(a.example.org)我有一个
url('^users/$', 'example.accounts.list_users', name='list_users'),
表中的内容的URL配置。 于是,在一些global_menu.html
模板我有{% url list_users %}
,显然它的作品完美,造成“ /users/
”。
现在,有网站B(b.example.org),与A分享了很多内部的有共同的外观和感觉我想用同样的global_menu.html
现场B和希望{% url list_users %}
到输出“ http://a.example.org/users/
”。 什么是我能做到这一点的最好方法是什么?
目前,我使用单独的global_menu.html
为每个站点,但这违反了DRY原则,而不是真的很方便。 而且,是的,我使用的Django的contrib.sites
框架具有鲜明SITE_ID
定义小号settings.py
为每个站点,但尚未实际使用的任何其他地方。
更新 :目前我正在考虑重新实现的url
标签或猴子修补reverse()
调用原单,并在例外执行额外的一些“洋地址列表”中查找。 如果已经存在这样的事 - 我很乐意听到的。
预先感谢您的答案!
Answer 1:
我已经通过覆盖实现了它django.core.urlresolvers.reverse
与我的自定义函数:
from django.core import urlresolvers
from django.conf import settings
__real_reverse = urlresolvers.reverse
def reverse(viewname, urlconf=None, args=None, kwargs=None, prefix=None):
try:
return __real_reverse(viewname, urlconf, args, kwargs, prefix)
except urlresolvers.NoReverseMatch, no_match:
external_urlconfs = getattr(settings, 'EXTERNAL_URLCONFS', [])
for p, c in external_urlconfs:
c = urlresolvers.RegexURLResolver(r'^/', c)
try:
return p + c.reverse(viewname, *args, **kwargs)
except urlresolvers.NoReverseMatch:
pass
raise no_match
urlresolvers.reverse = reverse
随后上市的URLconf在settings.py
是这样的:
ROOT_URLCONF = 'project.urls_a'
EXTERNAL_URLCONFS = (
('http://b.example.com/', 'project.urls_b'),
)
Answer 2:
是的,你需要使自己的{% url %}
标签,它使用它自己反转法。
例如,专门针对反向的Site_A的URL配置,那么你可以使用的方法是这样的:
from django.core.urlresolvers import reverse
import site_a
def site_a_reverse(viewname, args=None, kwargs=None):
# If your sites share the same database, you could get prefix from Site.objects.get(pk=site_a.settings.SITE_ID)
prefix = 'http://a.example.com/' # Note, you need the trailing slash
reverse(viewname, urlconf=site_a.urls, args=args, kwargs=kwargs, prefix=prefix)
Answer 3:
反向利用@drdaeman相同的设置覆盖Django的1.7.x
# -*- coding: utf-8 -*-
from django.core import urlresolvers
from django.conf import settings
__real_reverse = urlresolvers.reverse
def reverse(viewname, urlconf=None, args=None, kwargs=None, prefix=None, current_app=None):
try:
return __real_reverse(viewname, urlconf, args, kwargs, prefix, current_app)
except urlresolvers.NoReverseMatch, no_match:
external_urlconfs = getattr(settings, 'EXTERNAL_URLCONFS', [])
for p, c in external_urlconfs:
urlconf = c
try:
return p + __real_reverse(viewname, urlconf, args, kwargs, prefix, current_app)
except urlresolvers.NoReverseMatch:
pass
raise no_match
urlresolvers.reverse = reverse
我把代码在urls.py文件在启动时执行
Answer 4:
我建议做两个变化。 (1)移动模板到一个目录下(而不是每个应用程序),如果您已经没有。 (2)调查新加入的URL 命名空间功能。
第一个变化将让你有一个共同的基础模板,并有选择地覆盖它的各种应用程序/网站。 第二个可能有助于使你的URL“干燥”。
文章来源: Django cross-site reverse URLs