2008-09-29 27 views
314

Tôi hiện đang xác định biểu thức chính quy để nắm bắt các thông số trong url, như được mô tả trong hướng dẫn. Làm cách nào để truy cập thông số từ url như một phần của đối tượng HttpRequest? My HttpRequest.GET hiện trả về đối tượng trống QueryDict.Chụp tham số url theo yêu cầu.GET

Tôi muốn tìm hiểu cách thực hiện việc này mà không cần thư viện để tôi có thể biết Django tốt hơn.

Trả lời

482

Nếu url của bạn là một cái gì đó như domain/search/?q=haha, Sau đó, bạn sẽ sử dụng request.GET.get('q', '').

q là thông số bạn muốn và '' là giá trị mặc định nếu không tìm thấy q.

Nếu bạn thay vì chỉ định cấu hình URLconf, Sau đó, ảnh chụp của bạn từ regex sẽ được chuyển đến hàm làm đối số (hoặc đối số được đặt tên).

Chẳng hạn như:

(r'^user/(?P<username>\w{0,50})/$', views.profile_page,), 

Sau đó, trong bạn views.py bạn sẽ phải

def profile_page(request, username): 
    # Rest of the method 
+7

Là '? Param =' cách duy nhất Django nhận ra các tham số? Có cách nào để sử dụng URLconf với HTTP.GET không? Tôi muốn làm/param/2. – sutee

+3

Kiểm tra phần thứ hai của câu trả lời của tôi liên quan đến việc thu thập URLconf và regex của bạn. – camflan

+1

Ok. Tôi hiện đang sử dụng phương pháp thứ hai. Có vẻ như họ là những cơ chế riêng biệt, và tôi đang cố gắng pha trộn chúng. Cảm ơn! – sutee

8

Đây không phải là chính xác những gì bạn yêu cầu, nhưng this snippet là hữu ích cho việc quản lý query_strings trong templates.

268

Để làm rõ lời giải thích camflan của, chúng ta hãy giả sử bạn có

  • sự cai trị url(regex=r'^user/(?P<username>\w{1,50})/$', view='views.profile_page')
  • một trong yêu cầu đến cho quy tắc phối http://domain/user/thaiyoshi/?message=Hi

URL sẽ bắt các phần của URL đường (ở đây "user/thaiyoshi/") và chuyển chúng đến chức năng xem cùng với đối tượng yêu cầu.

Chuỗi truy vấn (ở đây message=Hi) được phân tích cú pháp và tham số được lưu trữ dưới dạng QueryDict trong request.GET. Không có kết hợp hoặc xử lý thêm cho các tham số HTTP GET được thực hiện.

xem Chức năng này sẽ sử dụng cả hai phần được chiết xuất từ ​​đường dẫn URL và một tham số truy vấn:

def profile_page(request, username=None): 
    user = User.objects.get(username=username) 
    message = request.GET.get('message') 

Như một mặt lưu ý, bạn sẽ tìm ra phương thức yêu cầu (trong trường hợp này "GET", và cho các hình thức nộp thường là "POST") trong request.method. Trong một số trường hợp, bạn nên kiểm tra xem nó có phù hợp với những gì bạn mong đợi hay không.

Cập nhật: Khi quyết định có nên sử dụng đường dẫn URL hoặc các thông số truy vấn cho chuyển thông tin, sau đây có thể giúp:

  • sử dụng đường dẫn URL cho nguồn lực xác định duy nhất, ví dụ /blog/post/15/ (không phải /blog/posts/?id=15)
  • sử dụng thông số truy vấn để thay đổi cách hiển thị tài nguyên, ví dụ:/blog/post/15/?show_comments=1 hoặc /blog/posts/2008/?sort_by=date&direction=desc
  • để tạo URL thân thiện với con người, tránh sử dụng số ID và sử dụng ví dụ: ngày, danh mục và/hoặc sên: /blog/post/2008/09/30/django-urls/
+11

Đây là một câu trả lời thực sự tốt. Nó chắc chắn đã giúp tôi hiểu Django tốt hơn một chút. – Mark

+2

cách chúng ta có thể nhận được tất cả các giá trị tham số mà không đề cập đến tên – numerah

+0

@numerah request.GET là một từ điển Python. Bạn có thể ví dụ:lặp qua request.GET.items(). – akaihola

17
def some_view(request, *args, **kwargs): 
    if kwargs.get('q', None): 
     # Do something here .. 
12

tôi muốn chia sẻ một mẹo có thể giúp bạn tiết kiệm một chút thời gian.
Nếu bạn có kế hoạch để sử dụng một cái gì đó như thế này trong tập tin urls.py của bạn:

url(r'^(?P<username>\w+)/$', views.profile_page,), 

Mà về cơ bản có nghĩa là www.example.com/<username>. Hãy chắc chắn đặt nó ở cuối các mục URL của bạn, vì nếu không, nó có thể gây xung đột với các mục nhập URL theo sau, tức là truy cập một trong số chúng sẽ cung cấp cho bạn lỗi tuyệt vời: User matching query does not exist.

I ' đã tự trải nghiệm nó; hy vọng nó giúp!

+2

Ngoài ra, trong trường hợp này, bạn có thể muốn kiểm tra xem tên người dùng không trùng với các địa chỉ email khác. – DrKaoliN

34

Sử dụng GET

request.GET["id"] 

Sử dụng POST

request.POST["id"] 
+12

Trong khi điều này làm việc cho các khóa hiện có, các câu trả lời của camflan và akaihola đã sử dụng .get() để tránh các trường hợp ngoại lệ 'KeyError' trong trường hợp thiếu khóa. Nó sẽ là khôn ngoan để làm như vậy (ví dụ: 'request.POST.get ('id', '')'). – vastlysuperiorman

3

Đối với những tình huống mà bạn chỉ có đối tượng request bạn có thể sử dụng request.parser_context['kwargs']['your_param']

+0

Giả định rằng django-rest-framework đang được sử dụng, câu hỏi đặc biệt chỉ hỏi về việc sử dụng các tính năng cốt lõi. – anddam

+0

Bạn có chắc chắn về điều này? Tôi có thể kiểm tra điều này sau nhưng tôi nghĩ rằng tôi có nghĩa là sử dụng đối tượng yêu cầu được hỗ trợ thông qua các tính năng cốt lõi. –

+0

Nghĩa đen từ câu hỏi ban đầu: "Tôi muốn tìm hiểu cách thực hiện việc này mà không cần thư viện" – anddam

1

Bạn có hai cách phổ biến để làm điều đó trong trường hợp của bạn url trông giống như sau:

https://domain/method/?a=x&b=y 

v1:

Nếu khóa cụ thể là bắt buộc bạn có thể sử dụng:

key_a = request.GET['a'] 

này sẽ trả về một giá trị của a nếu chính tồn tại và một ngoại lệ nếu không muốn nói.

v2:

Nếu phím của bạn là không bắt buộc:

request.GET.get('a') 

Bạn có thể thử rằng nếu không có bất kỳ đối số này sẽ không sụp đổ. Vì vậy, bạn có thể quấn nó với try: except: và trả về HttpResponseBadRequest() chẳng hạn. Đây là một cách đơn giản để làm cho mã của bạn ít phức tạp hơn, mà không cần sử dụng xử lý Ngoại lệ đặc biệt.

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