python Django的不区分大小写的网址?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1515634/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Case insensitive urls for Django?
提问by Software Enthusiastic
It seems by default django's url solver perform case sensitive search for solving url and differentiate between '/Login' and 'login'. My url patterns are as follows.
似乎默认情况下 django 的 url 解算器执行区分大小写的搜索来解决 url 并区分“/登录”和“登录”。我的网址模式如下。
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),
)
Can anyone please guide me, how to make django urls case insensitive?
任何人都可以指导我,如何使 django url 不区分大小写?
回答by Alex Martelli
Just put (?i)
at the start of every r'...'
string, i.e.:
只需放在(?i)
每个r'...'
字符串的开头,即:
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),
)
to tell every RE to match case-insensitively -- and, of course, live happily ever after!-)
告诉每个 RE 不区分大小写匹配——当然,从此过上幸福的生活!-)
回答by notsofast
In Django 2.1, it appears that (?i)
placed anywhereinside the URL regex will cause it to ignore case. However, reverse()
fails unless the (?i)
follows the $
at the end of the regex.
在 Django 2.1 中,似乎(?i)
放置在 URL 正则表达式中的任何位置都会导致它忽略大小写。但是,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') ]
raises
加注
ValueError: Non-reversible reg-exp portion: '(?i'
but runs cleanly with the regex r'home/$(?i)'
.
但使用正则表达式干净地运行r'home/$(?i)'
。
回答by chrki
With Django 2.0 (released in December 2017) the recommended way to use regular expressions for URL-matching is now re_path
instead of url
:
在 Django 2.0(2017 年 12 月发布)中,使用正则表达式进行 URL 匹配的推荐方法现在re_path
改为url
:
from django.urls import path, re_path
from . import views
urlpatterns = [
re_path(r'^(?i)admin/(.*)', admin.site.root),
re_path(r'^(?i)something/(?P<somestring>\w+)/$', views.something),
re_path(r'^(?i)login/$', views.login),
re_path(r'^(?i)logout/$', views.logout),
]
回答by Sym
Django 2.2 update
Django 2.2 更新
According to this ticket:
根据这张票:
Support for inline flags in regular expression groups ((?i), (?L), (?m), (?s), and (?u)) was deprecated in Django 1.11 and removed in Django 2.1
对正则表达式组((?i)、(?L)、(?m)、(?s) 和 (?u))中的内联标志的支持在 Django 1.11 中被弃用,并在 Django 2.1 中被移除
In Django 2.2 adding (?i)
to the start of a pattern produces this exception:
在 Django 2.2 中,添加(?i)
到模式的开头会产生以下异常:
ValueError: Non-reversible reg-exp portion
ValueError: Non-reversible reg-exp portion
confusingly, adding it to the end produces this warning:
令人困惑的是,将其添加到末尾会产生以下警告:
DeprecationWarning: Flags not at the start of the expression
DeprecationWarning: Flags not at the start of the expression
The new suggested wayto handle case insensative URLs in Django is to use a custom 404 handler.
在 Django 中处理不区分大小写的 URL的新建议方法是使用自定义 404 处理程序。
FWIW, that ticket also suggests "case-insensitive URLs aren't a good practice", however it doesn't provide any more arguement for this.
FWIW,那张票还表明“不区分大小写的 URL 不是一个好习惯”,但是它没有为此提供更多的争论。
There is a package on PyPi called django-icase
that looks like a good option
PyPi 上有一个包django-icase
,看起来是个不错的选择
回答by Danut Popa
You could also manage this from your view. For instance, if you have a generic.DetailView, you could override get_querysetmethod and set the slugvalue to lower case:
你也可以从你的角度管理这个。例如,如果您有一个 generic.DetailView,您可以覆盖get_queryset方法并将slug值设置为小写:
models.py:
模型.py:
from django.db import models
from django.utils.text import slugify
class MyModel(models.Model):
"""MyModel
"""
# name attribute is used to generate slug
name = models.CharField(max_length=25, verbose_name='Name', unique=True)
slug = models.SlugField(unique=True, verbose_name='Slug')
# override save method to generate slug
def save(self, force_insert=False, force_update=False, using=None,
update_fields=None):
self.slug = slugify(self.name)
super(MyModel, self).save(force_insert=False, force_update=force_update, using=using, update_fields=update_fields)
views.py:
视图.py:
from django.views import generic
class MyModelDetailView(generic.DetailView):
"""MyModelDetailView
Detail view of MyObject.
"""
model = MyModel
template_name = 'my_models/my_model_detail.html'
def get_queryset(self):
try:
self.kwargs['slug'] = self.kwargs['slug'].lower()
except Exception as err:
print(err)
pass
queryset = self.model.objects.filter()
return queryset
urls.py:
网址.py:
from . import views
from django.conf.urls import url
url(r'^my_model_detail/(?P<slug>[-\w]+)/$', views.MyModelDetailView.as_view(),
name='my_model_detail'),