7

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

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

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

http://www.amazon.fr/Nouveautés-paraître-Livres/(fr :书籍=> 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"),
                       )

url 模式需要在模板中基于 tld 和更高版本构建,<a href="{% url books %}" >{% trans "books" %}</a>以将 html 呈现为<a href="Bücher">Bücher</a><a href="Livres">Livres</a>

4

3 回答 3

13

您必须在网络服务器级别执行此操作(例如在 Apache 中使用 mod_rewrite)或使用中间件(例如此代码段

另请参阅此 SO 问题


更新:在您发表评论后,我想了更多。我喜欢 Carl Meyer 的回答,但后来意识到它无法正确处理 {% url %} 倒车。所以这就是我要做的:

多个站点:您需要使用Django 站点框架。这意味着使用 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 *

... 等等。

多个 URL conf:如上所述,每个站点的 url conf:

# 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 %}将正确反转,并且域名将是 Site 对象的 domain_name 字段,带有SITE_ID.

多个 Web 服务器实例:为了让每个站点正常工作,它们都需要自己的服务器实例。对于 apache + mod_wsgi,这意味着每个站点都有一个不同的 wsgi 应用程序,如下所示:

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

...等等,以及每个站点的匹配 apache 虚拟主机:

<VirtualHost *:80>
    ServerName mybooks.fr
    WSGIScriptAlias / /path/to/site_fr.wsgi
    ...
</VirtualHost>

希望这很清楚:)

于 2009-03-24T07:55:07.570 回答
8

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

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 可以分别拥有您需要的所有 URL,并采用适当的语言。

于 2009-03-24T14:37:48.680 回答
-1

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

于 2009-03-24T10:24:24.217 回答