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

45 投票
7 回答
17145 浏览
提问于 2025-04-15 14:47

看起来,默认情况下,Django的URL解析器在处理网址时是区分大小写的,也就是说它会把'/Login'和'login'当作不同的地址。我的网址模式如下。

urlpatterns = patterns('',
    (r'^admin/(.*)', admin.site.root),
    (r'^static/(?P<path>.*)$', 'django.views.static.serve',
        {'document_root': settings.STATIC_DOC_ROOT, 'show_indexes': True}),
    (r'^login/$', 'django.contrib.auth.views.login'),
    (r'^logout/$', do_logout),
)

有没有人能告诉我,怎么让Django的网址不区分大小写呢?

7 个回答

4

Django 2.2 更新

根据这个问题

在Django 1.11中,正则表达式组中的内联标志(比如 (?i)、(?L)、(?m)、(?s) 和 (?u))已经被弃用,并在Django 2.1中被移除了。

在Django 2.2中,如果在模式的开头加上(?i),会出现这个错误:

ValueError: 非可逆的正则表达式部分

而如果把它加到结尾,会出现这个警告:

DeprecationWarning: 标志不在表达式的开头

处理不区分大小写的URL的新建议方法是使用自定义404处理器

顺便提一下,这个问题也提到“大小写不敏感的URL不是一个好习惯”,不过没有提供更多的理由。

在PyPi上有一个叫django-icase的包,看起来是个不错的选择。

22

在Django 2.1中,似乎只要在URL的正则表达式中放入(?i),就可以让它忽略大小写,不管放在哪里都可以。不过,使用reverse()的时候,如果(?i)不放在正则表达式的结尾,也就是$后面,就会出错。

from django.urls import re_path, reverse
from django.shortcuts import render

def home_page(request):
    foo = reverse('home_page')
    return render(request, 'home.html')

urlpatterns = [ re_path(r'home/(?i)', home_page, name='home_page') ]

会抛出错误

ValueError: Non-reversible reg-exp portion: '(?i'

但是用正则表达式r'home/$(?i)'就能正常运行。

92

只需在每个 r'...' 字符串的开头加上 (?i),也就是说:

urlpatterns = patterns('',
(r'^(?i)admin/(.*)', admin.site.root),
(r'^(?i)static/(?P<path>.*)$', 'django.views.static.serve',
    {'document_root': settings.STATIC_DOC_ROOT, 'show_indexes': True}),
(r'^(?i)login/$', 'django.contrib.auth.views.login'),
(r'^(?i)logout/$', do_logout),
)

这样就可以让每个正则表达式都不区分大小写地进行匹配——当然,接下来就可以快乐地生活下去了!-)

撰写回答