首页 > 解决方案 > 如果 slug 在 Django 3.0 中使用印度尼西亚语的多语言网站上以“id-”开头,则会出现 404 错误

问题描述

http://example.com/de/id-button/ - 200 OK

http://example.com/id/id-button/ - 200 OK

http://example.com/any-other-slug/ - 200 OK

http://example.com/id-button/ - 404 错误:

Using the URLconf defined in example.urls, Django tried these URL patterns, in this order:
id/
The current path, id-button/, didn't match any of these.

urls.py 文件:

urlpatterns = i18n_patterns(
    path('admin/', admin.site.urls),
    path('', cache_page(cache_homepage)(homepage_views.index), name='index'),
    path('search/', search_views.search, name='search'),
    path('<slug:slug>/', item_views.item, name='item'),
    prefix_default_language=False,
)

该项目在数据库“id-button”中有一个 slug 字段。如果我将其重命名为“idbutton”: http ://example.com/idbutton/ - 200 OK

但我需要有这样的网址:http ://example.com/id-button/

更新: 它被接受为一个错误,但它现在没有移动: https ://code.djangoproject.com/ticket/31540

标签: djangodjango-viewsdjango-urlsdjango-i18ndjango-errors

解决方案


LocaleMiddleware这是由于和之间的相互作用i18n_patterns

LocaleMiddleware看到请求进来时,它会尝试从请求中解析语言。有关使用的正则表达式,请参阅https://github.com/django/django/blob/92507bf3ea4dc467f68edf81a686548fac7ff0e9/django/utils/translation/trans_real.py#L46 。允许的格式是:任何单词字符序列,以及可选的破折号和更多单词字符,之后它期望字符串的结尾或/. 在这种情况下,它匹配id-domain/,并理解这id-domain是该请求的语言前缀,从而导致 Django 激活该id语言。

然后,请求通过 URL 路由层,作为第一站之一到达https://github.com/django/django/blob/master/django/urls/resolvers.py#L301。该get_language()命令返回id,因此搜索的前缀是id/id-domain/不匹配。由于LocalePrefixPattern是顶级解析器,它不匹配不会导致其他任何尝试。

(它是 Django 中的错误吗?也许,我希望它看到id-domain/语言会使其也用于 URL 解析的语言前缀。但即使那样它也可能无法解决您的问题)


推荐阅读