2010-03-22 37 views
65

Tôi phải tạo một url động theo url hiện tại. Sử dụng thẻ {% url %} là cách dễ nhất để làm điều đó, nhưng tôi cần tên url hiện tại để tạo một tên mới động.Cách lấy tên url hiện tại bằng Django?

Làm cách nào để có được tên url được gắn với urlconf dẫn đến chế độ xem hiện tại?

EDIT: Tôi biết tôi có thể thủ công url bằng cách sử dụng get_absolute_url nhưng tôi muốn tránh nó vì nó là một phần của một bài giảng và tôi muốn chứng minh chỉ có một cách để xây dựng các url.

Học sinh biết cách sử dụng {% url %}. Họ biết phải đối mặt với một vấn đề khi họ phải tạo ra một url hoàn chỉnh hơn dựa trên hiện tại. Cách dễ nhất là sử dụng lại {% url %}, với một số biến thể. Vì chúng tôi đã đặt tên url là , chúng tôi cần biết cách lấy tên của url gọi là chế độ xem hiện tại.

EDIT 2: trường hợp sử dụng khác là hiển thị các phần của mẫu cơ sở khác nhau tùy theo mẫu cơ sở. Có nhiều cách khác để làm điều đó (sử dụng CSS và {% block%}, nhưng đôi khi thật tuyệt khi có thể xóa thẻ của mục nhập của base.html nếu tên hiển thị khớp với liên kết.

+5

Tôi tiếp tục tìm câu hỏi này trong khi tìm kiếm cách xuất ** url tuyệt đối, hiện tại qua thẻ mẫu ** ... nếu bạn đang tìm kiếm điều đó, đó là: '{{request .get_full_path}} ' – Dolph

Trả lời

85

Tôi không biết tính năng này đã là một phần của Django bao lâu nhưng như following article cho thấy, nó có thể đạt được như sau trong giao diện:

from django.core.urlresolvers import resolve 
    current_url = resolve(request.path_info).url_name 

Nếu bạn cần điều đó trong mỗi mẫu, viết một yêu cầu mẫu có thể thích hợp.

Edit: XIN MỚI Django CẬP NHẬT

Sau khi cập nhật Django hiện tại:

Django 1,10 (link)

Importing from the django.core.urlresolvers module is deprecated in favor of its new location, django.urls

Django 2,0 (link)

The django.core.urlresolvers module is removed in favor of its new location, django.urls .

Như vậy, đúng cách để làm là như thế này:

from django.urls import resolve 
current_url = resolve(request.path_info).url_name 
+0

Tại sao? Theo như tôi đã hiểu câu hỏi của bạn, một phần quan trọng của nó là làm thế nào để đạt được "Vì chúng tôi đã đặt tên url, chúng ta cần phải biết làm thế nào để có được tên của url được gọi là xem hiện tại." ... –

+1

Trên thực tế lukas Tôi đã gắt gỏng ngày hôm đó và loại bỏ câu trả lời của bạn hoàn toàn tùy tiện. Tôi xin lỗi, bởi vì đây thực sự là câu trả lời đúng. Tôi sẽ chỉnh sửa nó để làm cho nó trở nên ghê tởm hơn. –

+8

'resolve()' không thể giải quyết nếu bạn vượt qua nó một chuỗi truy vấn và đơn giản là tăng 404. 'get_full_path()' trả về đường dẫn và chuỗi truy vấn. Bạn sẽ cần sử dụng 'resolve (request.path_info)'. –

0

Đó là một chút không rõ ràng từ câu hỏi của bạn, nhưng http://docs.djangoproject.com/en/dev/topics/http/urls/ có thể sẽ cung cấp một lời giải thích cho những gì bạn đang sau

Đặc biệt hữu ích cần lưu ý cách Django xử lý các yêu cầu:.

Khi người dùng yêu cầu một trang từ của bạn Trang web được hỗ trợ bởi Django, đây là thuật toán mà hệ thống theo sau để xác định cod cod Python nào e để thực thi:

  1. Django xác định mô-đun URL URL để sử dụng. Thông thường, đây là giá trị của cài đặt ROOT_URLCONF, nhưng nếu đối tượng HttpRequest đến có thuộc tính được gọi là urlconf (được đặt bởi xử lý yêu cầu phần mềm trung gian), giá trị của nó sẽ được sử dụng thay cho cài đặt ROOT_URLCONF.
  2. Django tải mô-đun Python và tìm kiếm các biến urlpatterns. Đây phải là một danh sách Python, theo định dạng được trả về bởi hàm django.conf.urls.defaults.patterns().
  3. Django chạy qua từng mẫu URL, theo thứ tự và dừng lại ở mẫu đầu tiên khớp với URL được yêu cầu.
  4. Khi một trong các regex phù hợp, nhập Django và gọi khung nhìn đã cho, đó là hàm Python đơn giản. Khung nhìn được thông qua một HttpRequest làm đối số đầu tiên của nó và bất kỳ giá trị nào được nắm bắt trong regex như các đối số còn lại.

Nếu bạn ngay sau khi đường dẫn đầy đủ, bạn có thể thử:

http://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.get_full_path

Tôi hy vọng rằng sẽ giúp - nó chỉ ra làm thế nào để sử dụng các mô-đun URLconf, và hy vọng sẽ giúp bạn điểm trong Đúng hướng.

+0

Cảm ơn nhưng tôi biết rằng :-) Tôi đã thêm một số giải thích để tránh hiểu lầm. –

3

Làm rõ câu hỏi: "Trong chế độ xem, làm thế nào để bạn có được tên của một mẫu url trỏ đến nó, giả sử có chính xác một mẫu url như vậy."

Điều này có thể được mong muốn vì những lý do đã nêu: từ trong chế độ xem, chúng tôi muốn có cách UY để nhận url tới cùng một chế độ xem (chúng tôi không muốn biết tên urlpattern của chính chúng tôi)

Câu trả lời ngắn gọn: Nó không đủ đơn giản để dạy lớp học của bạn, nhưng có thể là một điều thú vị để bạn có thể làm trong một hoặc hai giờ và ném lên GitHub.

Nếu bạn thực sự muốn làm điều này, bạn sẽ phải phân lớp RegexURLResolver và sửa đổi phương thức phân giải để trả lại mẫu phù hợp (từ đó bạn có thể lấy tên mẫu) thay vì các cặp xem và cặp từ khóa/giá trị. http://code.djangoproject.com/browser/django/trunk/django/core/urlresolvers.py#L142Sau đó, bạn có thể tạo một trình trang trí hoặc có lẽ phần mềm trung gian thích hợp hơn sử dụng phân lớp này để lấy tên mẫu và lưu trữ giá trị đó ở đâu đó trong yêu cầu để các chế độ xem có thể sử dụng nó.

Nếu bạn thực sự muốn làm điều đó và bạn gặp một số rắc rối, hãy cho tôi biết và tôi có thể giúp đỡ.

Đối với lớp học của bạn, tôi sẽ chỉ yêu cầu họ mã hóa tên mẫu trong chế độ xem hoặc mẫu. Tôi tin rằng đây là cách chấp nhận được.

Cập nhật: Tôi càng nghĩ về điều này, tôi càng không muốn cố gắng lấy tên urlpattern trong chế độ xem. thông số urlpattern khá độc lập với các tham số của chế độ xem mà chúng trỏ đến. Nếu bạn muốn trỏ đến một url nhất định, bạn cần biết cách hoạt động của urlpattern, không chỉ cách hoạt động của chế độ xem. Nếu bạn cần biết cách urlpattern hoạt động, bạn cũng có thể phải biết tên của urlpattern.

91

Tính đến Django 1.5, điều này có thể được truy cập từ các đối tượng yêu cầu

current_url = request.resolver_match.url_name 

https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.resolver_match

+0

Khi tôi đã đặt điều này trong một bộ xử lý ngữ cảnh nó hoạt động, nhưng lỗi lạ này được hiển thị trong giao diện điều khiển: đối tượng 'AttributeError: 'WSGIRequest' không có thuộc tính 'resolver_match'' – fjsj

+1

' resolver_match 'chỉ được thêm vào đối tượng yêu cầu sau khi gọi tất cả phần mềm trung gian yêu cầu. Đó là khi các url đang được giải quyết. Vì vậy, bạn có thể truy cập chỉ từ phần mềm trung gian xem trở đi. (các hàm process_view của phần mềm trung gian). Nó sẽ không có sẵn trong các hàm trung gian yêu cầu. (các hàm process_request của phần mềm trung gian). – Bharathwaaj

+2

Có, nhưng lỗi này xảy ra trên một bộ xử lý ngữ cảnh mẫu. – fjsj

7

này có thể đạt được thông qua:

request.resolver_match.url_name 

Django> 1,8

15

Đối với những người không gian tên url của họ các mẫu, sau đó bạn có thể quan tâm đến tên url không gian tên của yêu cầu. Trong trường hợp này, Django gọi nó là view_name.

request.resolver_match.view_name 

# return: <namespace>:<url name> 
+0

Cảm ơn bạn, nhưng điều này là khá nhiều so với câu trả lời trước đó của @ dariusz-niespodziany, phải không? http://stackoverflow.com/a/31931833/1450294 –

+4

Nếu bạn không đặt tên cho 'urls.py' thì @ dariusz-niespodziany ngay lập tức có thể 'đảo ngược'. Nhưng nếu bạn đang sử dụng không gian tên, thì 'resolver_match.url_name' không trực tiếp 'đảo ngược'. Do đó bạn phải tự thêm không gian tên. Vì vậy, thay vì tự mình làm, Django đã đặt ['.view_name'] (https://github.com/django/django/blob/1.10.6/django/urls/resolvers.py#L51) khi khởi tạo. – Yeo

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