[Django]-Django i18n_patterns – How to prevent prefixing of non-active languages

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.

πŸ‘€Chillar Anand

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:

  1. 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)

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

πŸ‘€AlvaroAV

Leave a comment