Django 3.0 中不区分大小写的 URL?

Posted

技术标签:

【中文标题】Django 3.0 中不区分大小写的 URL?【英文标题】:Case insensitive URLS in Django 3.0? 【发布时间】:2020-06-26 00:02:51 【问题描述】:

有没有办法让 Django 2.0 及更高版本的 URL 不区分大小写?

例如

path('profile/<str:username>/add/',views.AddFriendRedirect.as_view(),name='add_friend'),

如果我做了profile/USERNAME,当用户名是全小写的用户名时,我怎样才能使它 不区分大小写吗?所以即使 uSERnAmE 也是有效的

我知道旧的url 语法有问题和答案,但我想知道新的path 语法是否可行

【问题讨论】:

这能回答你的问题吗? Case insensitive urls for Django? 不,因为我想知道path 语法是否可行,而不是urlre_path 语法 【参考方案1】:

有没有办法让 Django 2.0 及更高版本的 URL 不区分大小写?

如果完整的 url 不区分大小写,除了linked SO post 中的答案,我看不到任何其他方式。但我从 OP 收集到的是,只有用户名部分不区分大小写。如果我们按照正则表达式(?i) 的解决方案,这个url 也将是有效的PrOFile/UsERname/AdD

但看起来 OP 只希望用户名比较不区分大小写。使用str 转换器,无论在 url 中传递什么,都将按原样传递给视图。所以在真正意义上,它已经不区分大小写了。这里建议的方法应该是在视图中使用username__iexact 来获取用户。

但是,我们希望传递给视图的用户名值与视图要求的格式相同,例如小写,我们可以register 自定义路径转换器。

因为 OP 最初使用 string converter,我们可以扩展它并覆盖 to_python 以将值转换为小写。我在这里使用小写,因为在 OP 中提到用户名是小写的。

class IStringConverter(StringConverter):

    def to_python(self, value):
        return value.lower()

# once done, register it as:
register_converter(IStringConverter, 'istr')

# and use it as:
path('profile/<istr:username>/add/',views.AddFriendRedirect.as_view(),name='add_friend'),

【讨论】:

我认为这会起作用,但是,即使在对 StringConverter 和 register_converter 进行了正确的导入之后,我也会收到此错误 SyntaxError: trailing comma not allowed without surrounding parenthesesregister_converter(IStringConverterr, 'istr') NameError: name 'IStringConverterr' is not defined 它看起来像 1) 你使用 path 就像那样。我的意思是你应该在现有代码中修改它,无论它是以前编写的。 2) IStringConverterr 没有定义,因为有错字。最后还有一个额外的r。我已经在代码中解决了这个问题。 我刚刚意识到我打错了所以你的答案是正确的。太感谢了!我整天都被困在这上面【参考方案2】:

另一种解决方案是通过自定义中间件将非小写路径重定向到小写路径。

这是您要添加的中间件:

from django.contrib.redirects.middleware import RedirectFallbackMiddleware    

class CustomRedirectFallbackMiddleware(RedirectFallbackMiddleware):
    
    def process_response(self, request, response):
        if response.status_code != 404:
            return response

        full_path = request.get_full_path()

        if not full_path.islower():
            return self.response_redirect_class(full_path.lower())

【讨论】:

以上是关于Django 3.0 中不区分大小写的 URL?的主要内容,如果未能解决你的问题,请参考以下文章

处理 URL 中不区分大小写的应用程序名称

字符串属性的 gql 查询中不区分大小写的 where 子句

Google App Engine 数据存储区中不精确查询的良好模式是啥?

Oracle中不区分大小写的主键

grails中不区分大小写的搜索

在 QAbstractItemModel 中不区分大小写排序