1π
The best solution(I know) is to use solid-i18n-urls.
Install the package:
pip install solid_i18n
Modify settings a little bit:
# Default language, that will be used for requests without language prefix
LANGUAGE_CODE = 'en'
# supported languages
LANGUAGES = (
('en', 'English'),
('ru', 'Russian'),
)
# enable django translation
USE_I18N = True
#Add SolidLocaleMiddleware instead of LocaleMiddleware to MIDDLEWARE_CLASSES:
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'solid_i18n.middleware.SolidLocaleMiddleware',
'django.middleware.common.CommonMiddleware',
)
Use solid_i18n_patterns instead of i18n_patterns
from django.conf.urls import patterns, include, url
from solid_i18n.urls import solid_i18n_patterns
urlpatterns = solid_i18n_patterns('',
url(r'^main/$', 'about.view', name='about'),
)
Now, if you go to example.com/en/main
it works fine as en
is specified in your languages linst but if you go to example.com/ch/main
it throws a 404 page not found error.
1π
This is not a direct solution, but may help you or point you to a good solution.
- What about a custom middleware ?
Here we have 2 options:
-
A middleware where you check the country of the user and redirect to your allowed countries (If the user country is not allowed, you can redirect to a custom url or show a 404 error)
-
A middleware where you check the url-path of the client, so you will have
/country_code/url
and you can do as above, if the path is not allowed you can redirect to a custom url or show a 404 error
Little examples:
1. A middleware to check country
pygeoIP is used in the example to get country by ip
import pygeoip
class CountryMiddleware:
def process_request(self, request):
allowed_countries = ['GB','ES', 'FR'] # Add your allowed countries
gi = pygeoip.GeoIP('/usr/share/GeoIP/GeoIP.dat', pygeoip.MEMORY_CACHE)
ip = request.META.get('REMOTE_ADDR')
user_country = gi.country_code_by_addr(ip)
if user_country not in allowed_countries:
return HttpResponse... # Here you decide what to do if the url is not allowed
# Show 404 error
# or Redirect to other page...
2. A middleware to check url
class DomainMiddleware:
def process_request(self, request):
"""Parse out the subdomain from the request"""
# You especify full path or root paths
# If you specify '/en' as allowed paths, '/en/whatever' are allowed
ALLOWED_PATHS = ['/en','/fr', '/es'] # You add here allowed paths'
path = request.path
can_access = False
for url in ALLOWED_PATHS: # Find if the path is an allowed url
if url in path: # If any allowed url is in path
can_access=True
break
if not can_access: # If user url is not allowed
return HttpResponse... # Here you decide what to do if the url is not allowed
# Show 404 error
# or Redirect to other page...
If you decide to use any of this options you have to remember:
- You need to add middleware files in the path
your_project/middleware/middlewarefile.py
-
You need to add middlewares on your settings.py:
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', # etc..... 'yourproject.middleware.domainmiddleware.DomainMiddleware',
)
-
The code I showed here is not completed or tested, itβs an orientation to help you find a good soluiton