如何在Django中根据域名或TLD设置urlpatter?

时间:2009-03-24 07:43:54

标签: django session request django-urls

如何在Django中根据域名或TLD设置urlpatter?

对于某些链接,亚马逊会根据其网站tld以母语显示网址。

http://www.amazon.de/bücher-buch-literatur/(de:books =>bücher)

http://www.amazon.fr/Nouveautés-paraître-Livres/(fr:books => Livres)

http://www.amazon.co.jp/和書-ユーズドブッ-英語学習/(jp:books =>和书)

(链接不完整,只显示为样本。)

是否可以在urls.py中获取主机名? (请求对象在urls.py中不可用)或者可能在process_request中间件中并在urls.py中使用它(如何???)

任何替代建议如何实现这一目标?

#---------- pseudocode ---------- 

website_tld = get_host(request).split(".")[-1]

#.fr French  : Books : Livres
#.de German : Books : Bücher

if website_tld == "fr":
    lang_word = "Livres"
elif website_tld == "de":
    lang_word = "Bücher"
else:
    lang_word = "books"

urlpatterns = patterns('',
                       url(r'^%s/$' % lang_word,books_view, name="books"),
                       )

需要根据tld构建网址格式,稍后在模板<a href="{% url books %}" >{% trans "books" %}</a>中构建,以将html呈现为<a href="Bücher">Bücher</a><a href="Livres">Livres</a>

3 个答案:

答案 0 :(得分:12)

您必须在Web服务器级别(例如在Apache中使用mod_rewrite)或使用中间件(例如this snippet

执行此操作

另见this SO question


更新:在您发表评论之后我再考虑了一下。我喜欢Carl Meyer的回答,但后来意识到它无法正确处理{%url%}。所以这就是我要做的事情:

多个网站:您需要使用Django sites framework。这意味着使用Django管理员为每种语言制作网站实例。

多项设置:每种语言网站也都有自己的settings.py.每个网站之间的唯一区别是SITE_IDROOT_URLCONF设置,因此,为了遵循DRY原则,您应该将公共设置保存在不同的文件中,并将其导入到主文件中,如这样:

# settings_fr.py
SITE_ID = 1
ROOT_URLCONF = 'app.urls_fr'
from settings_common import *

# settings_de.py
SITE_ID = 2
ROOT_URLCONF = 'app.urls_de'
from settings_common import *

......等等。

多个网址:如上所述,每个网站都有一个网址:

# urls_fr.py
urlpatterns = patterns('',
    url(r'^Livres/$', books_view, name="books"),
)

# urls_de.py
urlpatterns = patterns('',
    url(r'^Bücher/$', books_view, name="books"),
)

......等等。

这样,url名称(在此示例中为“books”)对于所有语言都是相同的,因此{% url books %}将正确反转,域名将是具有{{1的Site对象的domain_name字段}}

多个Web服务器实例:为了使每个SITE正常工作,每个SITE都需要自己的服务器实例。对于apache + mod_wsgi,这意味着每个SITE的不同wsgi应用程序如下:

SITE_ID

...依此类推以及每个站点匹配的apache虚拟主机:

# site_fr.wsgi
import os, sys, django.core.handlers.wsgi
os.environ['DJANGO_SETTINGS_MODULE'] = 'app.settings_fr'
application = django.core.handlers.wsgi.WSGIHandler()

希望这很清楚:)

答案 1 :(得分:8)

您可以使用通过request.META ['HTTP_HOST']检索TLD的中间件来执行此操作,并将其添加到request.path;然后,您的根URLconf可以根据TLD作为第一个URL路径段切换到特定于语言的URLconf。这样的事情(未经测试!):

class PrependTLDMiddleware:
""" Prepend the top level domain to the URL path so it can be switched on in 
a URLconf. """

def process_request(self, request):
    tld = request.META['HTTP_HOST'].split('.')[-1]
    request.path = "/%s%s" % (tld, request.path)

在你的URLconf中:

urlpatterns = patterns('',
    url(r'^de/' include('de_urls')),
    url(r'^fr/', include('fr_urls')),
    url(r'^[^/]+/', include('en_urls'))
)

然后de_urls.py,fr_urls.py和en_urls.py可能都会以适当的语言提供您需要的所有网址。

答案 2 :(得分:-1)

在django中有一个名为“Sites”的表。也许你可以用它做点什么?