Django:用户名的urlpattern?

Django: urlpattern for username?

到目前为止,一位队友将此代码用于 url 用户名模式:

# urls.py
urlpatterns = patterns('...',
   url(r'^user/(?P<username>[.-_\w]+)/foo', 'myapp.views.foo'),
   ....

有一个隐藏的错误:如果用户名包含 - 则反转将失败,因为正则表达式模式的开头 [.-_ 表示 "all chars from . to _".

什么模式可以用来匹配所有个有效的用户名?

PS:如果你想在 django 中匹配所有可能的用户名,我想在正则表达式中添加 - 符号是不够的。

您可以将连字符移动到字符 class、

的开头
[-.\w]

或者你可以用反斜杠转义它

[.\-\w]

注意我已经删除了下划线,因为它包含在 \w 中。我还假设您只想接受 .-\w,并且您不想接受从 ._ 的所有字符].该范围包括 @ 等字符,因此您可能需要检查所有用户名是否与新的正则表达式匹配。

根据我在 AbstractUser 模型中看到的内容,我认为用于获取用户名的更好的正则表达式是 (?P<username>[\w.@+-]+).

首先,这不是bug而是一个特性well documented in the docs:

[]

Used to indicate a set of characters. In a set:

Ranges of characters can be indicated by giving two characters and separating them by a '-', for example [a-z] will match any lowercase ASCII letter, [0-5][0-9] will match all the two-digits numbers from 00 to 59, and [0-9A-Fa-f] will match any hexadecimal digit. If - is escaped (e.g. [a-z]) or if it’s placed as the first or last character (e.g. [a-]), it will match a literal '-'.

因此,在两个文字之间使用 - 会将正则表达式评估为字符范围:

re.compile("[a-0]+")
>> error: bad character range
re.findall("[.-_]+", "asdasd-asdasdad._?asdasd-")
>> ['._?']

如您所见,当在字符集中的字符之间使用时,python 将始终将 - 解释为范围指示符。

正如文档中(也)所述,通过使用 \- 转义 - 或将其作为字符集中的第一个或最后一个文字来避免范围声明[]

如果您想捕获包括 - 在内的字符范围,请尝试:

re.findall("[.-_\-]+", "asdasd-asdasdad._?asdasd-")
>> ['-', '._?', '-']

注: \w 在未设置 LOCALE 和 UNICODE 标志时等于 [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')

您可以使用以下方式:

[-.\w]- 用在最左边)

[.\-\w]-在任何地方使用反斜杠)

[.\w-]-用在最右边)

如果您使用特殊字符,那么最好在任何特殊字符(用于正则表达式特殊字符)之前使用 \(反斜杠)。

为了获得最佳使用效果,您的正则表达式应为 ^user/(?P<username>[.\-_\w]+)/foo

我认为您不应该在 URL 模式中加入任何用户名验证。将您的验证保存在一个地方——您第一次创建帐户的地方。

应该匹配用户在那里提供的任何内容,并将其传递给安全的数据库函数以查找用户名,如果不存在则失败。

因此,在您的 url 模式中,让浏览器发送任何非空的内容,并依靠您非常智能的数据库来告诉您您之前确定的内容是否有效。

url(r'^user/(?P<username>.+)/foo$', 'myapp.views.foo'),

另外,请注意末尾的“$”。