How do I set urlpatterns based on domain name or TLD, in Django?
如何在Django中根据域名或TLD设置urlpatter?
For some links, Amazon shows url in native language based on its website tld.
对于某些链接,亚马逊根据其网站tld以母语显示网址。
http://www.amazon.de/bücher-buch-literatur/ ( de : books => bücher )
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.fr/Nouveautés-paraître-Livres/(fr:books => Livres)
http://www.amazon.co.jp/和書-ユーズドブッ-英語学習/ ( jp : books => 和書 )
http://www.amazon.co.jp/和书 - ユーズドブッ - 英语学习/(jp:books =>和书)
( the links are incomplete and just show as samples. )
(链接不完整,只显示为样本。)
Is it possible to get host name in urls.py? (request object is not available in urls.py) or maybe in process_request of middleware and use it in urls.py(how???)
是否可以在urls.py中获取主机名? (请求对象在urls.py中不可用)或者可能在process_request中间件中并在urls.py中使用它(如何???)
Any alternate suggestions how to achive this?
任何替代建议如何实现这一目标?
#---------- 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"),
)
The url pattern needs to be built based on tld and later in the template, <a href="{% url books %}" >{% trans "books" %}</a>
to render html as <a href="Bücher">Bücher</a>
or <a href="Livres">Livres</a>
网址模式需要基于tld构建,稍后在模板中, {%trans“books”%} 将html呈现为Bücher或 Livres
3 个解决方案
#1
12
You have to do this at the webserver level (for example using mod_rewrite in Apache) or with middleware (for example this snippet)
您必须在Web服务器级别(例如在Apache中使用mod_rewrite)或使用中间件(例如此代码段)执行此操作
Also see this SO question
另见这个问题
Update: after your comment I thought about it some more. I liked Carl Meyer's answer, but then realized it wouldn't handle {% url %} reversing properly. So here's what I would do:
更新:在您发表评论之后我再考虑了一下。我喜欢Carl Meyer的回答,但后来意识到它无法正确处理{%url%}。所以这就是我要做的:
Multiple sites: You need to use the Django sites framework. Which means making site instances for each language using the Django admin.
多个站点:您需要使用Django站点框架。这意味着使用Django管理员为每种语言制作网站实例。
Multiple settings: Each language site will also have its own settings.py. The only differences between each site will be the SITE_ID
and ROOT_URLCONF
settings so, to follow DRY principle, you should keep the common settings in a different file and import them into the master file like this:
多种设置:每种语言网站也都有自己的settings.py。每个站点之间的唯一区别是SITE_ID和ROOT_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 *
... and so on.
... 等等。
Multiple URL conf: As implied above, a url conf for each site:
多个网址:如上所述,每个网站的网址配置为:
# 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"),
)
... and so on.
... 等等。
This way the url name (in this example "books") is the same for all languages, and therefore {% url books %}
will reverse properly and the domain name will be the domain_name field of the Site object with SITE_ID
.
这样,所有语言的URL名称(在此示例中为“books”)都是相同的,因此{%url books%}将正确反转,域名将是具有SITE_ID的Site对象的domain_name字段。
Multiple web server instances: In order for each SITE to work properly they each need their own server instances. For apache + mod_wsgi this means a different wsgi application for each SITE like this:
多个Web服务器实例:为了使每个SITE正常工作,每个SITE都需要自己的服务器实例。对于apache + mod_wsgi,这意味着每个SITE的不同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()
... and so on along with matching apache virtual host for each site:
...等等以及每个站点的匹配apache虚拟主机:
<VirtualHost *:80>
ServerName mybooks.fr
WSGIScriptAlias / /path/to/site_fr.wsgi
...
</VirtualHost>
Hopefully this is clear :)
希望这很清楚:)
#2
8
You can probably do this with a middleware that retrieves the TLD via request.META['HTTP_HOST'] and prepends it to request.path; then your root URLconf can switch out to language-specific URLconfs based on the TLD as the first URL path segment. Something like this (untested!):
您可以使用通过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)
And in your URLconf:
在你的URLconf中:
urlpatterns = patterns('',
url(r'^de/' include('de_urls')),
url(r'^fr/', include('fr_urls')),
url(r'^[^/]+/', include('en_urls'))
)
And then de_urls.py, fr_urls.py, and en_urls.py could each have all the URLs you need in the appropriate language.
然后de_urls.py,fr_urls.py和en_urls.py可以使用适当的语言拥有您需要的所有URL。
#3
-1
In django there's a table called "Sites". Maybe you can do something with that?
在django,有一个名为“Sites”的表。也许你可以做点什么呢?
#1
12
You have to do this at the webserver level (for example using mod_rewrite in Apache) or with middleware (for example this snippet)
您必须在Web服务器级别(例如在Apache中使用mod_rewrite)或使用中间件(例如此代码段)执行此操作
Also see this SO question
另见这个问题
Update: after your comment I thought about it some more. I liked Carl Meyer's answer, but then realized it wouldn't handle {% url %} reversing properly. So here's what I would do:
更新:在您发表评论之后我再考虑了一下。我喜欢Carl Meyer的回答,但后来意识到它无法正确处理{%url%}。所以这就是我要做的:
Multiple sites: You need to use the Django sites framework. Which means making site instances for each language using the Django admin.
多个站点:您需要使用Django站点框架。这意味着使用Django管理员为每种语言制作网站实例。
Multiple settings: Each language site will also have its own settings.py. The only differences between each site will be the SITE_ID
and ROOT_URLCONF
settings so, to follow DRY principle, you should keep the common settings in a different file and import them into the master file like this:
多种设置:每种语言网站也都有自己的settings.py。每个站点之间的唯一区别是SITE_ID和ROOT_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 *
... and so on.
... 等等。
Multiple URL conf: As implied above, a url conf for each site:
多个网址:如上所述,每个网站的网址配置为:
# 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"),
)
... and so on.
... 等等。
This way the url name (in this example "books") is the same for all languages, and therefore {% url books %}
will reverse properly and the domain name will be the domain_name field of the Site object with SITE_ID
.
这样,所有语言的URL名称(在此示例中为“books”)都是相同的,因此{%url books%}将正确反转,域名将是具有SITE_ID的Site对象的domain_name字段。
Multiple web server instances: In order for each SITE to work properly they each need their own server instances. For apache + mod_wsgi this means a different wsgi application for each SITE like this:
多个Web服务器实例:为了使每个SITE正常工作,每个SITE都需要自己的服务器实例。对于apache + mod_wsgi,这意味着每个SITE的不同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()
... and so on along with matching apache virtual host for each site:
...等等以及每个站点的匹配apache虚拟主机:
<VirtualHost *:80>
ServerName mybooks.fr
WSGIScriptAlias / /path/to/site_fr.wsgi
...
</VirtualHost>
Hopefully this is clear :)
希望这很清楚:)
#2
8
You can probably do this with a middleware that retrieves the TLD via request.META['HTTP_HOST'] and prepends it to request.path; then your root URLconf can switch out to language-specific URLconfs based on the TLD as the first URL path segment. Something like this (untested!):
您可以使用通过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)
And in your URLconf:
在你的URLconf中:
urlpatterns = patterns('',
url(r'^de/' include('de_urls')),
url(r'^fr/', include('fr_urls')),
url(r'^[^/]+/', include('en_urls'))
)
And then de_urls.py, fr_urls.py, and en_urls.py could each have all the URLs you need in the appropriate language.
然后de_urls.py,fr_urls.py和en_urls.py可以使用适当的语言拥有您需要的所有URL。
#3
-1
In django there's a table called "Sites". Maybe you can do something with that?
在django,有一个名为“Sites”的表。也许你可以做点什么呢?