Django:用户名的urlpattern?
Posted
技术标签:
【中文标题】Django:用户名的urlpattern?【英文标题】:Django: urlpattern for username? 【发布时间】:2015-11-30 10:27:04 【问题描述】:到目前为止,一位队友使用此代码作为用户名的 url 模式:
# urls.py
urlpatterns = patterns('...',
url(r'^user/(?P<username>[.-_\w]+)/foo', 'myapp.views.foo'),
....
有一个隐藏的错误:如果用户名包含-
,则反转将失败,因为正则表达式模式[.-_
的开头表示“从.
到_
的所有字符”。
什么模式可以用来匹配所有个有效的用户名?
PS:如果你想匹配 django 中所有可能的用户名,我想在正则表达式中添加 -
符号是不够的。
【问题讨论】:
【参考方案1】:根据我在AbstractUser
模型中看到的情况,我认为用于获取用户名的更好的正则表达式是(?P<username>[\w.@+-]+)
。
【讨论】:
感谢您的回答。其他答案告诉我如何在正则表达式中包含破折号。这不是问题所在。它是关于匹配任何有效的用户名。【参考方案2】:我认为你不应该在你的 URL 模式中加入任何用户名验证。将您的验证保存在一个地方 - 您第一次创建帐户的地方。
您应该匹配用户在此处提供的任何内容,并将其传递给安全的数据库函数以查找用户名,如果不存在则失败。
因此,在您的 url 模式中,让浏览器发送任何非空的内容,并依靠您非常智能的数据库来告诉您之前确定的内容是否有效。
url(r'^user/(?P<username>.+)/foo$', 'myapp.views.foo'),
另外,请注意末尾的“$”。
【讨论】:
【参考方案3】:您可以将连字符移动到字符类的开头,
[-.\w]
或者你可以用反斜杠转义它
[.\-\w]
注意我已经删除了下划线,因为它包含在\w
中。我还假设您只想接受.
、-
和\w
,而您不想接受从.
到_
的所有字符。该范围包括@
等字符,因此您可能需要检查您的所有用户名是否与新的正则表达式匹配。
【讨论】:
【参考方案4】:您可以使用以下方式:
[-.\w]
(-
用在最左边)
或[.\-\w]
(-
在任何地方与反斜杠一起使用)
或[.\w-]
(-
用在最右边)
如果您使用特殊字符,则最好使用 \
(backslash ) 在任何特殊字符(用于正则表达式特殊字符)之前。
为了获得最佳使用,您的正则表达式将是 ^user/(?P<username>[.\-_\w]+)/foo
【讨论】:
【参考方案5】:首先,不是bug而是功能well documented in the docs:
[]
用于表示一组字符。在一组中:
可以通过给出两个字符并用'-'分隔它们来表示字符范围,例如[az]将匹配任何小写ASCII字母,[0-5][0-9]将匹配所有两个-数字从 00 到 59,并且 [0-9A-Fa-f] 将匹配任何十六进制数字。 如果 - 被转义(例如 [a-z])或者如果它被放置为第一个或最后一个字符(例如 [a-]),它将匹配一个文字 '-'。
因此,在两个文字之间使用-
会将正则表达式评估为字符范围:
re.compile("[a-0]+")
>> error: bad character range
re.findall("[.-_]+", "asdasd-asdasdad._?asdasd-")
>> ['._?']
如您所见,当在字符集中的字符之间使用时,python 总是将-
解释为范围指示符。
正如(也)在文档中所述,通过使用 \-
转义 -
或将其作为字符集 []
中的第一个或最后一个文字来避免范围声明
如果您想捕获包括-
在内的字符范围,请尝试:
re.findall("[.-_\-]+", "asdasd-asdasdad._?asdasd-")
>> ['-', '._?', '-']
注意: 当 LOCALE 和 UNICODE 标志未设置时,\w
等于 [a-zA-Z0-9_]
。所以你不需要再次声明_
在你的情况下:
url(r'^user/(?P<username>[-.\w]+)/foo', 'myapp.views.foo')
url(r'^user/(?P<username>[.\w-]+)/foo', 'myapp.views.foo')
url(r'^user/(?P<username>[.\-\w]+)/foo', 'myapp.views.foo')
除了-
用法之外,如果您使用默认的Django 用户名样式,那么@navneet35371 对有效字符集是正确的。您可以更改您的正则表达式字符集以包含 @
和 +
并使用
url(r'^user/(?P<username>[\w.@+-]+)/foo', 'myapp.views.foo')
【讨论】:
以上是关于Django:用户名的urlpattern?的主要内容,如果未能解决你的问题,请参考以下文章