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'),
另外,请注意末尾的“$”。
到目前为止,一位队友将此代码用于 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'),
另外,请注意末尾的“$”。