How to set urlpatterns based on domain name or TLD in Django?

How to set urlpatterns based on domain name or TLD in Django?

For some links, Amazon displays the URL in their native language based on its tld website.

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 => 和 書)

(The links are incomplete and simply appear as samples.)

Is it possible to get the hostname in urls.py? (the request object is not available in urls.py) or maybe in the process_request middleware and use it in urls.py (like ???)

Any alternative suggestions on how to achieve 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 template must 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>

+5
source share
3 answers

You must do this at the web server level (e.g. using mod_rewrite in Apache) or using middleware (e.g. this snippet )

Also see this SO question


Update: after your comment, I thought about it a little more. I liked Karl Meyer's answer, but then I realized that he would not process {% url%} in the reverse order. So here is what I will do:

Multiple sites: You need to use the Django site structure . This means creating site instances for each language using the Django admin.

A few 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 , therefore, to follow the DRY principle, you must save the general settings in another file and import them into the main file as follows:

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

... etc.

Multiple Conf URLs: As stated above, the URL 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"), ) 

... etc.

Thus, the name of the URL (in this example, “books”) is the same for all languages, so {% url books %} will be formatted correctly, and the domain name will be the domain_name field of the site object with SITE_ID .

Multiple instances of the web server:. For each SITE to work correctly, each of them needs its own server instances. For apache + mod_wsgi, this means a different wsgi application for each SITE, for example:

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

... etc. together with the corresponding apache virtual host for each site:

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

Hope this is clear :)

+12
source

Perhaps you can do this with middleware that retrieves the TLD via request.META ['HTTP_HOST'] and adds it to request.path; then your root URLconf may switch to language specific TLD-based URLconfs as the first segment of the URL path. 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 can have all the URLs you need in the appropriate language.

+8
source

Django has a table called "Sites". Maybe you can do something about this?

-1
source

All Articles