【问题标题】:Django i18n_patterns - How to prevent prefixing of non-active languagesDjango i18n_patterns - 如何防止非活动语言的前缀
【发布时间】:2014-10-14 18:38:13
【问题描述】:

在我的 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。

【问题讨论】:

  • 你对这些页面使用 cms 吗?如果是,是哪一个?
  • 还有你用的是什么版本的?

标签: python django internationalization django-i18n


【解决方案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 page not found 错误。

【讨论】:

  • 对不起@ChillarAnand。我相信你不明白我的问题或不明白固体 il8n 的作用。在您上面的示例中,我希望 www.example.com/es/main 显示 404 而不是 200。Solid i8ln 不会为您执行此操作。通过在我的网站上测试您的代码进行验证。
  • @keithhackbarth 如果我错了,请纠正我。使用上述过程,我制作了一个适合您要求的工作示例。只需克隆、安装要求、运行服务器即可。 github.com/ChillarAnand/django-internationalization-example.
  • 我真诚地道歉,在测试了你的例子之后,我让它工作了。我的问题是我没有从设置文件中删除预先存在的“django.middleware.locale.LocaleMiddleware”。非常感谢您的帮助!
  • 从 Django 1.10 开始,这可以在没有 solid-i18n-urls 的情况下完成。
【解决方案2】:

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

  • 自定义中间件怎么样?

这里我们有 2 个选项:

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

    李>
  2. 一个中间件,您可以在其中检查客户端的 url-path,因此您将拥有 /country_code/url,并且您可以按照上述方式进行操作,如果不允许该路径,您可以重定向到自定义 url 或显示 404错误

小例子:

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

    )

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-20
    • 1970-01-01
    • 2012-01-27
    • 1970-01-01
    • 2022-11-05
    • 1970-01-01
    • 2012-07-05
    • 2016-04-15
    相关资源
    最近更新 更多