Django i18n_patterns - 如何防止非活动语言的前缀

时间:2014-10-14 18:38:13

标签: python django internationalization django-i18n

在我的django settings.py文件中,我有六种活动语言:

LANGUAGES = (
('de', gettext_noop('German')),
('en', gettext_noop('English')),
('es', gettext_noop('Spanish')),
('fr', gettext_noop('French')),
('nl', gettext_noop('Dutch')),
('pt', gettext_noop('Portuguese')),
)

使用i18n模式时,这些页面效果很好:

 http://exmaple.com/de/main
 http://exmaple.com/nl/main
 etc...

但是,如果您在Google中搜索我的网站,您会看到多个语言前缀页面。一些我不支持的语言。其中一些甚至不存在:

http://examble.com/ch/main
http://exmaple.com/zz/main
etc..

我不确定为什么这些网页会被编入索引。它们不在我的站点地图中。但是,Django确实将它们作为页面提供服务。

问题,修改i18n_patterns的最佳方法是什么,以便它只允许在settings.py中定义的有效的活动语言?我希望所有其他2个字符前缀为404.

2 个答案:

答案 0 :(得分:1)

最好的解决方案(我知道)是使用solid-i18n-urls

安装包:

pip install solid_i18n

稍微修改设置:

# 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',
)

使用solid_i18n_patterns代替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'),
)

现在,如果你转到example.com/en/main它可以正常工作,因为你的语言linst中指定了en但是如果你转到example.com/ch/main它会抛出404页面未找到错误。

答案 1 :(得分:1)

这不是一个直接的解决方案,但可以帮助您或指出一个好的解决方案。

  • 自定义中间件怎么样?

这里我们有两个选择:

  1. 用于检查用户所在国家/地区并重定向到允许国家/地区的中间件(如果不允许用户所在国家/地区,则可以重定向到自定义网址或显示404错误)

  2. 您检查客户端的网址路径的中间件,因此您将拥有/country_code/url并且您可以执行上述操作,如果不允许路径,您可以重定向到自定义网址或显示404错误

  3. 小例子:

    1。用于检查国家/地区的中间件

    在示例中使用

    pygeoIP 来通过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。用于检查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... 
    

    如果您决定使用任何此选项,您必须记住:

    • 您需要在路径your_project/middleware/middlewarefile.py
    • 中添加中间件文件
    • 您需要在settings.py上添加中间件:

      MIDDLEWARE_CLASSES =(

      'django.middleware.common.CommonMiddleware',
      'django.contrib.sessions.middleware.SessionMiddleware',
      'django.contrib.auth.middleware.AuthenticationMiddleware',
      # etc.....
      'yourproject.middleware.domainmiddleware.DomainMiddleware',
      

    • 我在这里展示的代码没有完成或测试,这是一个帮助你找到一个好的解决方案的方向