How do I set urlpatterns based on domain name or TLD, in Django?

∥☆過路亽.° 提交于 2019-11-27 18:54:17
Van Gale

You have to do this at the webserver level (for example using mod_rewrite in Apache) or with middleware (for example this snippet)

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:

Multiple sites: You need to use the Django sites framework. Which means making site instances for each language using the Django admin.

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_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.

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:

# 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:

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

Hopefully this is clear :)

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

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:

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.

In django there's a table called "Sites". Maybe you can do something with that?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!