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&lt;username&gt;[\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&lt;username&gt;[.\-_\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?的主要内容,如果未能解决你的问题,请参考以下文章

Django路由

如何在 url django 中添加用户名

如何在 django 中显示其他用户信息

Django,COOKIES,SESSION完成用户登入

将用户重定向到主页 django 的问题

django:url的name属性