2015-09-04 18 views
6

Đến nay một đồng đội sử dụng mã này cho các mẫu url của tên người dùng:Django: urlpattern cho tên người dùng?

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

có một lỗi ẩn: Nếu tên người dùng chứa một - sự đảo ngược sẽ thất bại, kể từ đầu mô hình regex [.-_ có nghĩa là "tất cả các ký tự từ . đến _".

Mẫu nào có thể được sử dụng để khớp với tất cả tên người dùng hợp lệ?

PS: Tôi đoán việc thêm ký hiệu - vào regex là không đủ, nếu bạn muốn khớp với tất cả tên người dùng có thể có trong django.

Trả lời

5

Tôi không nghĩ rằng bạn nên đặt bất kỳ xác nhận tên trong mẫu URL của bạn. Giữ xác thực của bạn ở một nơi - nơi bạn tạo tài khoản của mình lần đầu tiên.

Bạn nên khớp với bất kỳ điều gì người dùng cung cấp ở đó và chuyển đến chức năng cơ sở dữ liệu an toàn để tra cứu tên người dùng và không thành công nếu không tồn tại.

Vì vậy, trong mẫu url của bạn, hãy để trình duyệt gửi bất kỳ thứ gì không trống và dựa vào cơ sở dữ liệu rất thông minh của bạn để cho bạn biết những gì bạn đã quyết định trước đó là hợp lệ hay không.

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

Ngoài ra, hãy lưu ý "$" ở cuối.

4

Bạn có thể di chuyển các dấu nối khi bắt đầu của lớp nhân vật,

[-.\w] 

hoặc bạn có thể thoát khỏi nó với một dấu chéo ngược

[.\-\w] 

Lưu ý tôi đã loại bỏ các dấu gạch dưới, vì nó là bao gồm trong \w. Tôi cũng giả định rằng bạn chỉ muốn chấp nhận ., -\w và bạn không muốn chấp nhận tất cả các ký tự từ . đến _. Phạm vi đó bao gồm các ký tự như @, vì vậy bạn có thể muốn kiểm tra xem tất cả tên người dùng của bạn có khớp với regex mới không.

7

Dựa trên những gì tôi thấy trong mô hình AbstractUser, tôi nghĩ rằng một regex tốt hơn để sử dụng để lấy tên người dùng là (?P<username>[\[email protected]+-]+).

+0

Cảm ơn bạn đã trả lời câu hỏi này. Các câu trả lời khác cho tôi biết cách bao gồm dấu gạch ngang trong regex. Đó không phải là câu hỏi. Đó là về việc khớp với bất kỳ tên người dùng hợp lệ nào. – guettli

0

Trước hết, nó không phải là một lỗi nhưng một tính năng well documented in the docs:

[]

Được sử dụng để chỉ ra một tập hợp các ký tự. Trong một bộ:

Phạm vi ký tự có thể được chỉ định bằng cách cho hai ký tự và tách chúng bằng dấu '-', ví dụ [az] sẽ khớp với bất kỳ chữ cái ASCII thường, [0-5] [0-9] sẽ khớp với tất cả các số có hai chữ số từ 00 đến 59 và [0-9A-Fa-f] sẽ khớp với bất kỳ chữ số thập lục phân nào. Nếu - được thoát (ví dụ [a-z]) hoặc nếu nó được đặt làm ký tự đầu tiên hoặc cuối cùng (ví dụ: [a-]), ký tự đó sẽ khớp với chữ '-'.

Vì vậy, sử dụng - giữa hai literals sẽ đánh giá regex mà như một loạt nhân vật:

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

Như bạn thấy, trăn sẽ luôn interperet - như một chỉ số phạm vi khi được sử dụng giữa các nhân vật trong bộ ký tự.

Vì nó là (cũng) được nêu trong các tài liệu, tránh một tuyên bố phạm vi được thực hiện bằng cách thoát khỏi sự - với \- hoặc đặt nó như là người đầu tiên hoặc cuối cùng chữ trong bộ ký tự []

Nếu bạn muốn chụp phạm vi nhân vật bao gồm -, sau đó thử:

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

Lưu ý:\w bằng [a-zA-Z0-9_] khi LOCALE và UNICODE cờ không được thiết lập. Vì vậy, bạn không cần phải khai báo _ lại

Và trong tình huống của bạn:

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') 

Ngoài việc sử dụng -, nếu bạn đang sử dụng mặc định Django Tên phong cách, sau đó @ navneet35371 là đúng về bộ ký tự hợp lệ. Bạn có thể thay đổi nhân vật regex của bạn thiết lập để bao gồm @+ và sử dụng

url(r'^user/(?P<username>[\[email protected]+-]+)/foo', 'myapp.views.foo') 
3

Bạn có thể dùng cách sau:

[-.\w] (- sử dụng trong hầu hết các trái)

hay[.\-\w] (- sử dụng dấu gạch chéo ngược ở bất kỳ nơi nào)

hay[.\w-] (- sử dụng theo đúng nghĩa nhất)

nếu bạn sử dụng ký tự đặc biệt thì sử dụng tốt nhất\ (backslash) trước khi bất kỳ ký tự đặc biệt (được sử dụng trong regex char đặc biệt.).

Để sử dụng tốt nhất regex của bạn sẽ được ^user/(?P<username>[.\-_\w]+)/foo

Các vấn đề liên quan