จะรับชื่อ url ปัจจุบันโดยใช้ Django ได้อย่างไร?


91

ฉันต้องสร้าง url แบบไดนามิกตาม url ปัจจุบัน การใช้{% url %}แท็กเป็นวิธีที่ง่ายที่สุด แต่ฉันต้องการชื่อ url ปัจจุบันเพื่อสร้างชื่อใหม่แบบไดนามิก

ฉันจะรับชื่อ url ที่แนบมากับ urlconf ที่นำไปสู่มุมมองปัจจุบันได้อย่างไร

แก้ไข: ฉันรู้ว่าฉันสามารถสร้าง URL ได้ด้วยตนเองโดยใช้get_absolute_urlแต่ฉันควรหลีกเลี่ยงเนื่องจากเป็นส่วนหนึ่งของการบรรยายและฉันต้องการสาธิตวิธีเดียวในการสร้าง URL

{% url %}นักเรียนรู้วิธีการใช้ พวกเขารู้ดีว่ากำลังเผชิญกับปัญหาเมื่อต้องสร้าง url ที่สมบูรณ์มากขึ้นตาม URL ปัจจุบัน วิธีที่ง่ายที่สุดคือใช้{% url %}อีกครั้งโดยมีรูปแบบต่างๆ เนื่องจากเราตั้งชื่อ url เราจึงต้องรู้วิธีรับชื่อ url ที่เรียกมุมมองปัจจุบัน

แก้ไข 2: กรณีการใช้งานอื่นคือการแสดงส่วนต่างๆของเทมเพลตพื้นฐานที่แตกต่างกันไปตามเทมเพลตพื้นฐาน มีวิธีอื่นในการทำเช่นนี้ (โดยใช้ CSS และ {% block%} แต่ในบางครั้งก็เป็นการดีที่สามารถลบแท็กของรายการเมนูของ base.html ได้หากชื่อมุมมองตรงกับลิงก์


6
ฉันยังคงพบคำถามนี้ในขณะที่ค้นหาวิธีส่งออกurl ปัจจุบันที่แน่นอนผ่านแท็กเทมเพลต ... หากคุณกำลังมองหาสิ่งนั้นเช่นกันนั่นคือ:{{ request.get_full_path }}
Dolph

คำตอบ:


134

ฉันไม่รู้ว่าฟีเจอร์นี้เป็นส่วนหนึ่งของ Django มานานแค่ไหนแล้ว แต่จากบทความต่อไปนี้แสดงให้เห็นว่าสามารถทำได้ดังต่อไปนี้ในมุมมอง:

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

หากคุณต้องการสิ่งนั้นในทุกเทมเพลตการเขียนคำขอเทมเพลตก็เหมาะสม

แก้ไข: ใช้การอัปเดต DJANGO ใหม่

ติดตามการอัปเดต Django ปัจจุบัน:

Django 1.10 ( ลิงค์ )

การนำเข้าจากdjango.core.urlresolversโมดูลถูกเลิกใช้เพื่อสนับสนุนตำแหน่งใหม่django.urls

Django 2.0 ( ลิงค์ )

โมดูลจะถูกลบออกในความโปรดปรานของสถานที่ตั้งใหม่django.core.urlresolversdjango.urls

ดังนั้นวิธีที่ถูกต้องมีดังนี้:

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

ทำไม? เท่าที่ฉันเข้าใจคำถามของคุณส่วนสำคัญคือทำอย่างไรจึงจะบรรลุ "เนื่องจากเราตั้งชื่อ url เราจึงจำเป็นต้องรู้วิธีรับชื่อ url ที่เรียกมุมมองปัจจุบัน" ...
Lukas Bünger

1
จริงๆแล้ว lukas ฉันไม่พอใจในวันนั้นและทิ้งคำตอบของคุณโดยเด็ดขาด ฉันขอโทษเพราะนี่เป็นคำตอบที่ถูกต้อง ฉันจะแก้ไขเพื่อให้ชัดเจนยิ่งขึ้น
e-satis

8
resolve()ไม่สามารถแก้ไขได้หากคุณส่งสตริงแบบสอบถามและเพียงแค่เพิ่ม 404 get_full_path()ส่งคืนเส้นทางและสตริงแบบสอบถาม คุณจะต้องใช้resolve(request.path_info).
สามารถ Burak Çilingir

จะเกิดอะไรขึ้นถ้าไม่ใช่currenturl ที่ต้องแก้ไข แต่ผู้ใช้จะเปลี่ยนเส้นทางไป? วิธีทั่วไปในการบรรลุเป้าหมายนี้คืออะไร? คำตอบของ Conley Owens มีเงื่อนงำ แต่ฉันไม่อยากสร้างวงล้อใหม่หากล้อดังกล่าวมีอยู่แล้วใน Django ภายใต้ประทุน
Hassan Baig

ดูเหมือนจะใช้ไม่ได้กับ URL ที่แปลได้กับ i18n_patterns
guival

110

สำหรับ Django 1.5 สิ่งนี้สามารถเข้าถึงได้จากออบเจ็กต์คำขอ

current_url = request.resolver_match.url_name

หากคุณต้องการชื่อ url พร้อมกับเนมสเปซ

current_url = request.resolver_match.view_name

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


เมื่อฉันใส่สิ่งนี้ในตัวประมวลผลบริบทมันใช้งานได้ แต่ข้อผิดพลาดแปลก ๆ นี้ปรากฏในคอนโซล:AttributeError: 'WSGIRequest' object has no attribute 'resolver_match'
fjsj

2
'resolver_match' จะถูกเพิ่มลงในออบเจ็กต์คำขอหลังจากเรียกมิดเดิลแวร์คำขอทั้งหมด นั่นคือเมื่อ URL ได้รับการแก้ไข คุณจึงสามารถเข้าถึงได้จากมิดเดิลแวร์ดูเป็นต้นไปเท่านั้น (ฟังก์ชั่น process_view ของมิดเดิลแวร์) จะไม่มีในฟังก์ชันมิดเดิลแวร์คำขอ (ฟังก์ชัน process_request ของมิดเดิลแวร์)
Bharathwaaj

.view_nameหากคุณต้องการเนมสเปซ

29

สำหรับผู้ที่เนมสเปซรูปแบบ URL ของตนคุณอาจสนใจชื่อ url เนมสเปซของคำขอ ในกรณีนี้ Django เรียกมันว่าview_nameแทน

request.resolver_match.view_name

# return: <namespace>:<url name>

ขอบคุณ แต่นี่เป็นการหลอกลวงของ @ dariusz-niespodziany คำตอบก่อนหน้านี้ใช่ไหม stackoverflow.com/a/31931833/1450294
Michael Scheper

5
หากคุณไม่ได้ namespace ของคุณurls.pyแล้ว @ Dariusz-niespodziany ทันทีreverseน่า แต่ถ้าคุณกำลังใช้ namespace แล้วresolver_match.url_nameไม่ได้โดยตรงreverseน่า ดังนั้นคุณต้องต่อท้ายเนมสเปซด้วยตัวคุณเอง ดังนั้นแทนที่จะทำเอง Django ได้ตั้งค่าการ.view_nameเริ่มต้นแล้ว
Yeo


4

คำชี้แจงของคำถาม: "ในมุมมองคุณจะได้รับชื่อของรูปแบบ URL ที่ชี้ไปยังคำถามนี้ได้อย่างไรโดยสมมติว่ามีรูปแบบ URL แบบเดียวกัน"

สิ่งนี้อาจเป็นที่ต้องการด้วยเหตุผลที่ระบุไว้: จากในมุมมองเราต้องการวิธีที่แห้งในการรับ url ไปยังมุมมองเดียวกัน (เราไม่ต้องการทราบชื่อ urlpattern ของเราเอง)

คำตอบสั้น ๆ : มันไม่ง่ายพอที่จะสอนชั้นเรียนของคุณ แต่มันอาจจะเป็นเรื่องสนุกสำหรับคุณที่จะทำในหนึ่งหรือสองชั่วโมงแล้วทุ่มให้กับ GitHub

หากคุณต้องการทำสิ่งนี้จริงๆคุณจะต้องซับคลาส RegexURLResolver และแก้ไขวิธีการแก้ไขเพื่อส่งคืนรูปแบบที่ตรงกัน (ซึ่งคุณจะได้รับชื่อรูปแบบ) แทนการดูและคู่คำหลัก / ค่า http://code.djangoproject.com/browser/django/trunk/django/core/urlresolvers.py#L142

จากนั้นคุณสามารถสร้างมัณฑนากรหรือมิดเดิลแวร์ที่เหมาะสมกว่าซึ่งใช้คลาสย่อยนี้เพื่อรับชื่อรูปแบบและเก็บค่านั้นไว้ที่ใดที่หนึ่งในคำขอเพื่อให้มุมมองสามารถใช้งานได้

หากคุณต้องการทำเช่นนั้นจริงและพบปัญหาบางอย่างโปรดแจ้งให้เราทราบและฉันอาจช่วยได้

สำหรับชั้นเรียนของคุณฉันจะให้พวกเขาฮาร์ดโค้ดชื่อรูปแบบในมุมมองหรือเทมเพลต ฉันเชื่อว่านี่เป็นวิธีที่ยอมรับได้

อัปเดต: ยิ่งฉันคิดถึงเรื่องนี้มากเท่าไหร่ฉันก็จะยิ่งท้อใจในการพยายามหาชื่อรูปแบบ URL ในมุมมอง พารามิเตอร์ urlpattern ค่อนข้างไม่ขึ้นกับพารามิเตอร์ของมุมมองที่ชี้ไป หากคุณต้องการชี้ไปที่ URL ใด URL หนึ่งคุณจำเป็นต้องรู้ว่ารูปแบบ URL ทำงานอย่างไรไม่ใช่แค่การทำงานของมุมมองเท่านั้น หากคุณต้องการทราบว่า urlpattern ทำงานอย่างไรคุณอาจต้องทราบชื่อของ urlpattern ด้วย




1

คำถามของคุณไม่ชัดเจนเล็กน้อย แต่http://docs.djangoproject.com/en/dev/topics/http/urls/จะให้คำอธิบายสิ่งที่คุณต้องการ

มีประโยชน์อย่างยิ่งในการสังเกตว่า Django ประมวลผลคำขออย่างไร:

เมื่อผู้ใช้ร้องขอเพจจากไซต์ที่ขับเคลื่อนด้วย Django ของคุณนี่คืออัลกอริทึมที่ระบบต่อไปนี้เพื่อกำหนดว่าโค้ด Python ใดที่จะดำเนินการ:

  1. Django กำหนดโมดูล URLconf รูทที่จะใช้ โดยทั่วไปนี่คือค่าของการตั้งค่า ROOT_URLCONF แต่ถ้าวัตถุ HttpRequest ขาเข้ามีแอตทริบิวต์ที่เรียกว่า urlconf (กำหนดโดยการประมวลผลคำขอมิดเดิลแวร์) ค่าของมันจะถูกใช้แทนการตั้งค่า ROOT_URLCONF
  2. Django โหลดโมดูล Python นั้นและค้นหาตัวแปร urlpatterns นี่ควรเป็นรายการ Python ในรูปแบบที่ส่งคืนโดยฟังก์ชัน django.conf.urls.defaults.patterns ()
  3. Django ทำงานผ่านแต่ละรูปแบบ URL ตามลำดับและหยุดที่รูปแบบแรกที่ตรงกับ URL ที่ร้องขอ
  4. เมื่อหนึ่งใน regexes ตรงกัน Django จะนำเข้าและเรียกใช้มุมมองที่กำหนดซึ่งเป็นฟังก์ชัน Python อย่างง่าย มุมมองได้รับการส่งผ่าน HttpRequest เป็นอาร์กิวเมนต์แรกและค่าใด ๆ ที่จับใน regex เป็นอาร์กิวเมนต์ที่เหลือ

หากคุณอยู่ตามเส้นทางแบบเต็มคุณสามารถลอง:

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

ฉันหวังว่าจะช่วย - มันบ่งบอกถึงวิธีการใช้โมดูล URLconf และหวังว่าจะช่วยชี้ให้คุณไปในทิศทางที่ถูกต้อง


ขอบคุณ แต่ฉันรู้ว่า :-) ฉันได้เพิ่มคำอธิบายเพื่อหลีกเลี่ยงความเข้าใจผิด
e-satis
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.