เมื่อฉันอ่านรหัส Django reverse()
บางครั้งที่ฉันเห็นในบางแม่ ฉันไม่แน่ใจว่าสิ่งนี้คืออะไร แต่มันถูกใช้ร่วมกับ HttpResponseRedirect reverse()
ควรใช้สิ่งนี้อย่างไรและเมื่อไหร่?
มันจะดีถ้ามีคนให้คำตอบด้วยตัวอย่างบางส่วน ...
เมื่อฉันอ่านรหัส Django reverse()
บางครั้งที่ฉันเห็นในบางแม่ ฉันไม่แน่ใจว่าสิ่งนี้คืออะไร แต่มันถูกใช้ร่วมกับ HttpResponseRedirect reverse()
ควรใช้สิ่งนี้อย่างไรและเมื่อไหร่?
มันจะดีถ้ามีคนให้คำตอบด้วยตัวอย่างบางส่วน ...
คำตอบ:
สมมติว่าurls.py
คุณได้กำหนดสิ่งนี้ไว้ใน:
url(r'^foo$', some_view, name='url_name'),
ในเทมเพลตคุณสามารถอ้างถึง url นี้เป็น:
<!-- django <= 1.4 -->
<a href="{% url url_name %}">link which calls some_view</a>
<!-- django >= 1.5 or with {% load url from future %} in your template -->
<a href="{% url 'url_name' %}">link which calls some_view</a>
สิ่งนี้จะแสดงผลเป็น:
<a href="/foo/">link which calls some_view</a>
ตอนนี้ว่าคุณต้องการที่จะทำบางสิ่งบางอย่างที่คล้ายกันในของคุณviews.py
- เช่นคุณมีการจัดการ URL อื่น ๆ บาง (ไม่/foo/
) ในบางมุมมองอื่น ๆ (ไม่ได้some_view
) และคุณต้องการที่จะเปลี่ยนเส้นทางให้ผู้ใช้/foo/
(มักจะเป็นกรณีการส่งแบบฟอร์มการประสบความสำเร็จ)
คุณสามารถทำได้:
return HttpResponseRedirect('/foo/')
แต่ถ้าคุณต้องการเปลี่ยน URL ในอนาคตล่ะ คุณต้องอัปเดตurls.py
และการอ้างอิงทั้งหมดในรหัสของคุณ สิ่งนี้ละเมิดDRY (อย่าทำซ้ำตัวเอง)ความคิดทั้งหมดในการแก้ไขเพียงแห่งเดียวเท่านั้นซึ่งเป็นสิ่งที่เราต้องพยายาม
คุณสามารถพูดได้ว่า:
from django.urls import reverse
return HttpResponseRedirect(reverse('url_name'))
ลักษณะนี้ผ่าน URL ทั้งหมดที่กำหนดไว้ในโครงการของคุณสำหรับ URL ที่กำหนดไว้มีชื่อurl_name
และส่งกลับ /foo/
URL
ซึ่งหมายความว่าคุณหมายถึง URL โดยเฉพาะของname
แอตทริบิวต์ - ถ้าคุณต้องการที่จะเปลี่ยน URL ตัวเองหรือมุมมองมันหมายถึงคุณสามารถทำได้โดยการแก้ไขที่เดียวเท่านั้น urls.py
-
{{ url 'url_name' }}
ควรอยู่{% url url_name %}
ใน Django 1.4 หรือเก่ากว่า นี้จะมีการเปลี่ยนแปลงในรุ่น Django ถัดไป (1.5) {% url 'url_name' %}
และจากนั้นควรจะเป็น เอกสารสำหรับtemplatetag ของ urlให้ข้อมูลที่ดีถ้าคุณเลื่อนลงไปที่ส่วน "การทำงานร่วมกันได้ต่อไป"
url_reverse
ปีและยังไม่ได้ตอบสนองความต้องการสำหรับ วิธีที่ดีที่สุดในการจัดการกับสิ่งแปลกประหลาดประเภทนี้คือการปฏิเสธที่จะใช้มัน
นี่เป็นคำถามเก่า แต่นี่คือสิ่งที่อาจช่วยใครบางคน
จากเอกสารอย่างเป็นทางการ:
Django มีเครื่องมือสำหรับการย้อนกลับ URL ที่ตรงกับเลเยอร์ต่างๆที่จำเป็นต้องใช้ URL: ในเทมเพลต: การใช้แท็กเทมเพลต url ในรหัสไพ ธ อน: การใช้ฟังก์ชัน reverse () ในรหัสระดับที่สูงขึ้นเกี่ยวข้องกับการจัดการ URL ของอินสแตนซ์โมเดล Django: เมธอด get_absolute_url ()
เช่น. ในเทมเพลต (แท็ก url)
<a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a>
เช่น. ในรหัสหลาม (ใช้reverse
ฟังก์ชั่น)
return HttpResponseRedirect(reverse('news-year-archive', args=(year,)))
คำตอบที่มีอยู่ทำได้ดีมากในการอธิบายว่าreverse()
ฟังก์ชัน นี้ใน Django เป็นอย่างไร
แต่ผมหวังว่าคำตอบของฉันหลั่งน้ำตาแสงที่แตกต่างกันที่ว่าทำไมทำไมการใช้งานreverse()
ในสถานที่ตรงไปตรงมามากขึ้นวิธีการเนื้อหา pythonic อื่น ๆ ในแม่แบบของมุมมองที่มีผลผูกพันและสิ่งที่เป็นบางเหตุผลที่ถูกต้องสำหรับความนิยมของคนนี้ "เปลี่ยนเส้นทางผ่าน reverse()
รูปแบบ "ในตรรกะการกำหนดเส้นทาง Django
ประโยชน์ที่สำคัญอย่างหนึ่งคือการสร้าง URL ย้อนกลับตามที่คนอื่น ๆ ได้กล่าวถึง เช่นเดียวกับวิธีการที่คุณจะใช้{% url "profile" profile.id %}
ในการสร้าง URL จากแฟ้มการกำหนดค่า URL path('<int:profile.id>/profile', views.profile, name="profile")
ของแอปนี้เช่น
แต่เป็น OP ได้ตั้งข้อสังเกตการใช้ยังจะถูกรวมโดยทั่วไปกับการใช้งานของreverse()
HttpResponseRedirect
แต่ทำไม
ฉันไม่แน่ใจว่าสิ่งนี้คืออะไร แต่มันถูกใช้ร่วมกับ HttpResponseRedirect ควรใช้ reverse นี้อย่างไรและเมื่อใด?
พิจารณาสิ่งต่อไปนี้views.py
:
from django.http import HttpResponseRedirect
from django.urls import reverse
def vote(request, question_id):
question = get_object_or_404(Question, pk=question_id)
try:
selected = question.choice_set.get(pk=request.POST['choice'])
except KeyError:
# handle exception
pass
else:
selected.votes += 1
selected.save()
return HttpResponseRedirect(reverse('polls:polls-results',
args=(question.id)
))
และความเรียบง่ายของเราurls.py
:
from django.urls import path
from . import views
app_name = 'polls'
urlpatterns = [
path('<int:question_id>/results/', views.results, name='polls-results'),
path('<int:question_id>/vote/', views.vote, name='polls-vote')
]
ในvote()
ฟังก์ชั่นรหัสในelse
บล็อกของเราใช้reverse
พร้อมกับHttpResponseRedirect
ในรูปแบบต่อไปนี้:
HttpResponseRedirect(reverse('polls:polls-results',
args=(question.id)
สิ่งแรกและสำคัญที่สุดนี้หมายความว่าเราไม่จำเป็นต้องเข้ารหัสฮาร์ดโค้ด (สอดคล้องกับหลักการ DRY) แต่สำคัญยิ่งกว่านั้นreverse()
เป็นวิธีที่สวยงามในการสร้างสตริง URL โดยการจัดการค่าที่args=(question.id)
คลายจากอาร์กิวเมนต์ ( จัดการโดย URLConfig) ควรquestion
มีคุณสมบัติid
ที่มีค่า5
URL ที่สร้างจากreverse()
นั้นจะเป็น:
'/polls/5/results/'
ในรหัสการเชื่อมโยงมุมมองเทมเพลตปกติเราใช้HttpResponse()
หรือrender()
ตามปกติแล้วจะเกี่ยวข้องกับสิ่งที่เป็นนามธรรมน้อยกว่า: ฟังก์ชันหนึ่งมุมมองที่ส่งคืนหนึ่งเทมเพลต:
def index(request):
return render(request, 'polls/index.html')
แต่ในหลายกรณีการเปลี่ยนเส้นทางที่ถูกกฎหมายเรามักสนใจสร้าง URL จากรายการพารามิเตอร์ รวมถึงกรณีต่าง ๆ เช่น:
POST
คำขอสิ่งเหล่านี้ส่วนใหญ่เกี่ยวข้องกับการเปลี่ยนเส้นทางรูปแบบบางส่วนและ URL ที่สร้างผ่านชุดพารามิเตอร์ หวังว่านี่จะช่วยเพิ่มคำตอบที่เป็นประโยชน์แล้ว!
ฟังก์ชั่นรองรับหลักการแบบแห้ง - ให้แน่ใจว่าคุณไม่ได้ใส่รหัสยากในแอพของคุณ ควรกำหนด url ในที่เดียวและที่เดียวเท่านั้น - url ของคุณจะเป็นที่ยอมรับ หลังจากนั้นคุณเพียงแค่อ้างอิงข้อมูลนั้น
ใช้reverse()
เพื่อให้ URL ของหน้าเว็บที่กำหนดให้กับเส้นทางไปยังมุมมองหรือพารามิเตอร์ page_name จาก url conf ของคุณ {% url 'my-page' %}
คุณจะใช้มันในกรณีที่มันไม่ได้ทำให้ความรู้สึกที่จะทำมันในแม่แบบที่มี
มีสถานที่ที่เป็นไปได้มากมายที่คุณอาจใช้ฟังก์ชันนี้ ที่เดียวที่ฉันพบฉันใช้คือเมื่อเปลี่ยนเส้นทางผู้ใช้ในมุมมอง (บ่อยครั้งหลังจากการประมวลผลแบบฟอร์มสำเร็จ) -
return HttpResponseRedirect(reverse('thanks-we-got-your-form-page'))
คุณอาจใช้เมื่อเขียนแท็กเทมเพลต
อีกครั้งที่ฉันใช้reverse()
อยู่กับมรดกรุ่น ฉันมี ListView ในรูปแบบผู้ปกครอง แต่ต้องการได้รับจากวัตถุแม่ใด ๆ เหล่านั้นไปยัง DetailView ของวัตถุลูกที่เกี่ยวข้อง ผมแนบget__child_url()
ฟังก์ชั่นไปยังผู้ปกครองที่ระบุการดำรงอยู่ของเด็กและกลับ URL ของมัน DetailView reverse()
โดยใช้
มีเอกสารสำหรับสิ่งนั้น
https://docs.djangoproject.com/en/dev/topics/http/urls/#reverse-resolution-of-urls
มันสามารถใช้ในการสร้าง URL สำหรับมุมมองที่กำหนด
ข้อได้เปรียบหลักคือคุณไม่ได้กำหนดเส้นทางรหัสยากในรหัส
คำตอบที่มีอยู่ค่อนข้างชัดเจน ในกรณีที่คุณไม่ทราบสาเหตุที่เรียกว่าreverse
: จะใช้อินพุตของชื่อ URL และให้ URL จริงซึ่งจะย้อนกลับไปที่มี URL ก่อนแล้วจึงตั้งชื่อ
reverse () ใช้เพื่อยึดหลักการ django DRY เช่นหากคุณเปลี่ยน url ในอนาคตคุณสามารถอ้างอิง url นั้นโดยใช้ reverse (urlname)
url--> view name
. แต่บางครั้งเช่นเมื่อเปลี่ยนเส้นทางคุณต้องไปในทิศทางตรงกันข้ามและตั้งชื่อมุมมองให้ Django และ Django สร้าง URL ที่เหมาะสม กล่าวอีกนัยหนึ่ง,view name --> url
. นั่นคือreverse()
(มันคือการย้อนกลับของฟังก์ชัน url) มันอาจดูโปร่งใสกว่าที่จะโทรgenerateUrlFromViewName
แต่มันยาวเกินไปและอาจไม่กว้างพอ: docs.djangoproject.com/en/dev/topics/http/urls/ …