Django 2.1 - Conditional View Processing

सशर्त दृश्य प्रसंस्करण




django

सशर्त दृश्य प्रसंस्करण

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 अनुरोधों के लिए जाँच प्रदान करने के लिए भी किया जा सकता है। इन स्थितियों में, विचार को "संशोधित नहीं" प्रतिक्रिया वापस करने के लिए नहीं है, लेकिन क्लाइंट को यह बताने के लिए कि वे जिस संसाधन को बदलने की कोशिश कर रहे हैं, उस बीच में बदल दिया गया है।

उदाहरण के लिए, क्लाइंट और सर्वर के बीच निम्नलिखित विनिमय पर विचार करें:

  1. ग्राहक के अनुरोध /foo/
  2. सर्वर "abcd1234" ETag के साथ कुछ सामग्री के साथ प्रतिक्रिया करता है।
  3. ग्राहक संसाधन को अद्यतन करने के लिए /foo/ HTTP HTTP अनुरोध भेजता है। यह एक If-Match: "abcd1234" भी भेजता है If-Match: "abcd1234" शीर्षक को अद्यतन करने की कोशिश कर रहे संस्करण को निर्दिष्ट करने के लिए।
  4. सर्वर यह देखने के लिए जाँच करता है कि क्या संसाधन बदल गया है, ETag की गणना उसी तरह से करता है जैसे कि वह GET अनुरोध के लिए करता है (उसी फ़ंक्शन का उपयोग करके)। यदि संसाधन बदल गया है, तो यह 412 स्थिति कोड लौटाएगा, जिसका अर्थ है "पूर्व शर्त विफल"।
  5. ग्राहक 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 डेकोरेटर का उपयोग करने पर विचार करना चाहिए। यदि सब कुछ पहले से ही काफी तेज़ी से चलता है, तो मिडलवेयर और नेटवर्क ट्रैफ़िक की मात्रा का उपयोग करके ग्राहकों को वापस भेजा जाए, अगर दृश्य बदल गया है तब भी कम हो जाएगा।