Django 2.1 - Conditional View Processing
सशर्त दृश्य प्रसंस्करण

सशर्त दृश्य प्रसंस्करण
HTTP क्लाइंट एक सर्वर की प्रतियों के बारे में सर्वर को बताने के लिए कई हेडर भेज सकते हैं जो उन्होंने पहले ही देख लिए हैं।
आमतौर पर इसका उपयोग तब किया जाता है जब वेब पेज (HTTP
GET
अनुरोध का उपयोग करके) ग्राहक को पहले से प्राप्त किसी चीज के लिए सभी डेटा भेजने से बचने के लिए।
हालांकि, एक ही हेडर का उपयोग सभी HTTP तरीकों (
POST
,
PUT
,
DELETE
, आदि) के लिए किया जा सकता है।
Django एक दृश्य से वापस भेजता है कि प्रत्येक पृष्ठ (प्रतिक्रिया) के लिए, यह दो HTTP हेडर प्रदान कर सकता है:
ETag
हेडर और
Last-Modified
हेडर।
ये शीर्ष लेख HTTP प्रतिक्रियाओं पर वैकल्पिक हैं।
वे आपके दृश्य फ़ंक्शन द्वारा सेट किए जा सकते हैं, या आप
ETag
हेडर सेट करने के लिए
ConditionalGetMiddleware
मिडलवेयर पर भरोसा कर सकते हैं।
जब ग्राहक अगला उसी संसाधन का अनुरोध करता है, तो यह हेडर के साथ भेज सकता है जैसे कि
If-modified-since
या
If-unmodified-since
, अंतिम संशोधन समय की तारीख जिसमें इसे भेजा गया था, या तो
If-match
या
If-none-match
, जिसमें अंतिम
ETag
था जिसे भेजा गया था।
यदि पृष्ठ का वर्तमान संस्करण क्लाइंट द्वारा भेजे गए
ETag
मेल खाता है, या यदि संसाधन को संशोधित नहीं किया गया है, तो एक पूर्ण प्रतिक्रिया के बजाय, क्लाइंट को यह कहते हुए 304 स्थिति कोड वापस भेजा जा सकता है कि कुछ भी नहीं बदला है।
शीर्षलेख के आधार पर, यदि पृष्ठ को संशोधित किया गया है या ग्राहक द्वारा भेजे गए
ETag
मेल नहीं खाता है, तो 412 स्थिति कोड (Precondition Failed) वापस आ सकता है।
जब आपको अधिक महीन दाने वाले नियंत्रण की आवश्यकता होती है तो आप प्रति-दृश्य सशर्त प्रसंस्करण कार्यों का उपयोग कर सकते हैं।
condition
सजाने वाला
कभी-कभी (वास्तव में, काफी बार) आप पूरी तरह से निर्माण के लिए आवश्यक सभी ETag को करने के लिए बिना किसी संसाधन के ETag मान या अंतिम-संशोधित समय की तेजी से गणना करने के लिए फ़ंक्शन बना सकते हैं। Django तब इन कार्यों का उपयोग दृश्य प्रसंस्करण के लिए "शुरुआती खैरात" विकल्प प्रदान करने के लिए कर सकता है। क्लाइंट को यह बताना कि अंतिम अनुरोध के बाद से सामग्री को संशोधित नहीं किया गया है, शायद।
इन दो कार्यों को
django.views.decorators.http.condition
डेकोरेटर के मापदंडों के रूप में पारित किया जाता है।
यह डेकोरेटर दो कार्यों का उपयोग करता है (आपको केवल एक की आपूर्ति करने की आवश्यकता है, यदि आप दोनों मात्राओं को आसानी से और जल्दी से गणना नहीं कर सकते हैं) अगर वर्कआउट के हेडर संसाधन में उन मेल खाते से मेल खाते हैं।
यदि वे मेल नहीं खाते हैं, तो संसाधन की एक नई प्रति की गणना की जानी चाहिए और आपका सामान्य दृष्टिकोण कहा जाता है।
condition
सज्जाकार के हस्ताक्षर इस तरह दिखता है:
condition(etag_func=None, last_modified_func=None)
ETag और अंतिम संशोधित समय की गणना करने के लिए दो फ़ंक्शन, आने वाले
request
ऑब्जेक्ट और एक ही पैरामीटर, एक ही क्रम में पारित किए जाएंगे, क्योंकि वे जिस फ़ंक्शन को लपेटने में मदद कर रहे हैं।
अंतिम बार पारित किया गया
last_modified_func
को एक मानक
last_modified_func
मान लौटा देना चाहिए, जो संसाधन को संशोधित करने के अंतिम समय को निर्दिष्ट करता है, या संसाधन मौजूद नहीं होने पर
None
भी नहीं।
ETag
डेकोरेटर को दिया गया फ़ंक्शन संसाधन के लिए
ETag
प्रतिनिधित्व करने वाले स्ट्रिंग को वापस करना चाहिए, या यदि यह मौजूद नहीं है तो
None
भी नहीं।
डेकोरेटर ने
ETag
और
Last-Modified
हेडर्स को रिस्पॉन्स पर सेट किया है, अगर वे पहले से ही व्यू से सेट नहीं हैं और अगर रिक्वेस्ट का तरीका सुरक्षित है (
GET
या
HEAD
)।
इस सुविधा का उपयोगी उपयोग करना शायद एक उदाहरण के साथ सबसे अच्छा समझाया गया है। मान लीजिए कि आपके पास एक साधारण ब्लॉग सिस्टम का प्रतिनिधित्व करने वाले मॉडल की यह जोड़ी है:
import datetime from django.db import models class Blog(models.Model): ... class Entry(models.Model): blog = models.ForeignKey(Blog, on_delete=models.CASCADE) published = models.DateTimeField(default=datetime.datetime.now) ...
यदि फ्रंट पेज, नवीनतम ब्लॉग प्रविष्टियों को प्रदर्शित करता है, तो जब आप एक नया ब्लॉग प्रविष्टि जोड़ते हैं, तो केवल तभी परिवर्तन होता है, जब आप अंतिम संशोधित समय की गणना बहुत जल्दी कर सकते हैं।
आपको उस ब्लॉग से जुड़ी प्रत्येक प्रविष्टि के लिए नवीनतम
published
तिथि चाहिए।
ऐसा करने का एक तरीका यह होगा:
def latest_entry(request, blog_id): return Entry.objects.filter(blog=blog_id).latest("published").published
फिर आप इस फ़ंक्शन का उपयोग अपने सामने वाले पृष्ठ दृश्य के लिए अपरिवर्तित पृष्ठ का शीघ्र पता लगाने के लिए कर सकते हैं:
from django.views.decorators.http import condition @condition(last_modified_func=latest_entry) def front_page(request, blog_id): ...
सज्जाकारों के आदेश के साथ सावधान रहें
जब
condition()
सशर्त प्रतिक्रिया देता है, तो इसके नीचे कोई भी सज्जाकार छोड़ दिया जाएगा और प्रतिक्रिया पर लागू नहीं होगा।
इसलिए, किसी भी सज्जाकार को नियमित दृश्य प्रतिक्रिया और सशर्त प्रतिक्रिया दोनों के लिए आवेदन करने की आवश्यकता होती है जो
condition()
ऊपर होनी चाहिए।
विशेष रूप से,
vary_on_cookie()
,
vary_on_headers()
, और
cache_control()
पहले आना चाहिए क्योंकि
RFC 7232 के लिए
आवश्यक है कि वे जो हेडर सेट करते हैं वे 304 प्रतिक्रियाओं पर मौजूद हों।
केवल एक मूल्य की गणना के लिए शॉर्टकट
एक सामान्य नियम के रूप में, यदि आप ETag और अंतिम संशोधित समय दोनों की गणना करने के लिए कार्य प्रदान कर सकते हैं, तो आपको ऐसा करना चाहिए। आप नहीं जानते कि किसी भी HTTP क्लाइंट को कौन सा हेडर आपको भेजेगा, इसलिए दोनों को संभालने के लिए तैयार रहें। हालांकि, कभी-कभी केवल एक मूल्य की गणना करना आसान होता है और Django सज्जाकार प्रदान करता है जो केवल ETag या केवल अंतिम-संशोधित संगणनाओं को संभालता है।
django.views.decorators.http.etag
और
django.views.decorators.http.last_modified
डेकोरेटर उसी प्रकार के फ़ंक्शंस हैं, जैसे कि
django.views.decorators.http.last_modified
डेकोरेटर।
उनके हस्ताक्षर हैं:
etag(etag_func) last_modified(last_modified_func)
हम पहले के उदाहरण को लिख सकते हैं, जो केवल इन सजावटकर्ताओं में से एक का उपयोग करके एक अंतिम-संशोधित फ़ंक्शन का उपयोग करता है:
@last_modified(latest_entry) def front_page(request, blog_id): ...
... या:
def front_page(request, blog_id): ... front_page = last_modified(latest_entry)(front_page)
दोनों स्थितियों का परीक्षण करते समय
condition
उपयोग करें
यदि आप दोनों पूर्व शर्त का परीक्षण करना चाहते हैं तो यह कुछ लोगों को
last_modified
और
last_modified
डेकोरेटर्स को चेन करने के लिए अच्छे लग सकते हैं।
हालाँकि, यह गलत व्यवहार को बढ़ावा देगा।
# Bad code. Don't do this! @etag(etag_func) @last_modified(last_modified_func) def my_view(request): # ... # End of bad code.
पहला डेकोरेटर दूसरे के बारे में कुछ नहीं जानता है और जवाब दे सकता है कि प्रतिक्रिया को संशोधित नहीं किया गया है, भले ही दूसरा डेकोरेटर अन्यथा निर्धारित करेगा।
condition
सज्जाकार सही कार्रवाई करने के लिए दोनों कॉलबैक फ़ंक्शन का उपयोग करता है।
अन्य HTTP तरीकों के साथ डेकोरेटर का उपयोग करना
condition
डेकोरेटर केवल
GET
और
HEAD
अनुरोधों से अधिक के लिए उपयोगी है (
HEAD
अनुरोध इस स्थिति में
GET
के समान हैं)।
इसका उपयोग
POST
,
PUT
और
DELETE
अनुरोधों के लिए जाँच प्रदान करने के लिए भी किया जा सकता है।
इन स्थितियों में, विचार को "संशोधित नहीं" प्रतिक्रिया वापस करने के लिए नहीं है, लेकिन क्लाइंट को यह बताने के लिए कि वे जिस संसाधन को बदलने की कोशिश कर रहे हैं, उस बीच में बदल दिया गया है।
उदाहरण के लिए, क्लाइंट और सर्वर के बीच निम्नलिखित विनिमय पर विचार करें:
-
ग्राहक के अनुरोध
/foo/
। -
सर्वर
"abcd1234"
ETag के साथ कुछ सामग्री के साथ प्रतिक्रिया करता है। -
ग्राहक संसाधन को अद्यतन करने के लिए
/foo/
HTTP HTTP अनुरोध भेजता है। यह एकIf-Match: "abcd1234"
भी भेजता हैIf-Match: "abcd1234"
शीर्षक को अद्यतन करने की कोशिश कर रहे संस्करण को निर्दिष्ट करने के लिए। -
सर्वर यह देखने के लिए जाँच करता है कि क्या संसाधन बदल गया है, ETag की गणना उसी तरह से करता है जैसे कि वह
GET
अनुरोध के लिए करता है (उसी फ़ंक्शन का उपयोग करके)। यदि संसाधन बदल गया है, तो यह 412 स्थिति कोड लौटाएगा, जिसका अर्थ है "पूर्व शर्त विफल"। -
ग्राहक 412 प्रतिसाद प्राप्त करने के बाद
/foo/
अपडेट करने के लिए, सामग्री को अद्यतन करने से पहले सामग्री का एक अद्यतन संस्करणGET
करने के लिए/foo/
अनुरोध प्राप्त करता है।
इस उदाहरण से पता चलता है कि महत्वपूर्ण बात यह है कि सभी स्थितियों में ETag और अंतिम संशोधन मूल्यों की गणना करने के लिए समान कार्यों का उपयोग किया जा सकता है। वास्तव में, आपको समान फ़ंक्शन का उपयोग करना चाहिए , ताकि हर बार समान मान लौटाए जा सकें।
गैर-सुरक्षित अनुरोध विधियों के साथ मान्य हेडर
condition
डेकोरेटर सुरक्षित HTTP तरीकों, यानी
GET
और
HEAD
लिए केवल सत्यापनकर्ता हेडर (
ETag
और
Last-Modified
) सेट करता है।
यदि आप उन्हें अन्य मामलों में वापस करना चाहते हैं, तो उन्हें अपने विचार में सेट करें।
PUT
बनाम
POST
साथ किए गए अनुरोधों के जवाब में सत्यापनकर्ता हेडर सेट करने के बीच अंतर के बारे में जानने के लिए
RFC 7231 # अनुभाग-4.3.4
देखें।
मिडिलवेयर सशर्त प्रसंस्करण के साथ तुलना
Django,
ConditionalGetMiddleware
माध्यम से सरल और सरल सशर्त
GET
हैंडलिंग प्रदान करता है।
कई स्थितियों में उपयोग में आसान और उपयुक्त होने के बावजूद, मिडलवेयर की उन्नत उपयोग की सीमाएँ हैं:
- यह आपकी परियोजना के सभी विचारों के लिए विश्व स्तर पर लागू है।
- यह आपको प्रतिक्रिया उत्पन्न करने से नहीं बचाता है, जो महंगा हो सकता है।
-
यह केवल HTTP
GET
अनुरोधों के लिए उपयुक्त है।
आपको यहां अपनी विशेष समस्या के लिए सबसे उपयुक्त उपकरण चुनना चाहिए।
यदि आपके पास ETags और संशोधन समय को जल्दी से गणना करने का एक तरीका है और यदि सामग्री को उत्पन्न करने में कुछ समय लगता है, तो आपको इस दस्तावेज़ में वर्णित
condition
डेकोरेटर का उपयोग करने पर विचार करना चाहिए।
यदि सब कुछ पहले से ही काफी तेज़ी से चलता है, तो मिडलवेयर और नेटवर्क ट्रैफ़िक की मात्रा का उपयोग करके ग्राहकों को वापस भेजा जाए, अगर दृश्य बदल गया है तब भी कम हो जाएगा।