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
语法是否可行,而不是url
或re_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 parentheses
和 register_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?的主要内容,如果未能解决你的问题,请参考以下文章
字符串属性的 gql 查询中不区分大小写的 where 子句