Django 2.1 - Form Assets (the Media class)

फॉर्म एसेट्स (मीडिया वर्ग)




django

फॉर्म एसेट्स (मीडिया वर्ग)

एक आकर्षक और आसानी से उपयोग होने वाले वेब फॉर्म को प्रस्तुत करने के लिए केवल HTML से अधिक की आवश्यकता होती है - इसके लिए CSS स्टाइलशीट की भी आवश्यकता होती है, और यदि आप फैंसी "Web2.0" विजेट का उपयोग करना चाहते हैं, तो आपको प्रत्येक पृष्ठ पर कुछ जावास्क्रिप्ट शामिल करने की आवश्यकता हो सकती है। किसी पृष्ठ के लिए आवश्यक सीएसएस और जावास्क्रिप्ट का सटीक संयोजन उस पृष्ठ पर उपयोग किए जाने वाले विजेट पर निर्भर करेगा।

यह वह जगह है जहाँ परिसंपत्ति की परिभाषाएँ आती हैं। Django आपको विभिन्न फ़ाइलों - जैसे कि स्टाइलशीट्स और स्क्रिप्ट - को उन संपत्तियों और विजेट्स के साथ संबद्ध करने की अनुमति देता है, जिनके लिए उन परिसंपत्तियों की आवश्यकता होती है। उदाहरण के लिए, यदि आप DateFields को रेंडर करने के लिए कैलेंडर का उपयोग करना चाहते हैं, तो आप एक कस्टम कैलेंडर विजेट को परिभाषित कर सकते हैं। यह विजेट तब CSS और जावास्क्रिप्ट के साथ जुड़ा हो सकता है जो कैलेंडर को प्रस्तुत करने के लिए आवश्यक है। जब कैलेंडर विजेट का उपयोग किसी प्रपत्र पर किया जाता है, तो Django सीएसएस और जावास्क्रिप्ट फ़ाइलों की पहचान करने में सक्षम होता है जो आवश्यक हैं, और आपके वेब पेज पर आसान समावेश के लिए उपयुक्त रूप में फ़ाइल नामों की सूची प्रदान करते हैं।

संपत्ति और Django व्यवस्थापक

Django एडमिन एप्लिकेशन कैलेंडर, फ़िल्टर्ड चयनों और इतने पर के लिए कई अनुकूलित विजेट्स को परिभाषित करता है। ये विजेट संपत्ति की आवश्यकताओं को परिभाषित करते हैं, और Django एडमिन Django चूक के स्थान पर कस्टम विजेट का उपयोग करता है। व्यवस्थापक टेम्प्लेट में केवल वे फ़ाइलें शामिल होंगी जो किसी भी पृष्ठ पर विजेट को प्रस्तुत करने के लिए आवश्यक हैं।

आप Django व्यवस्थापक अनुप्रयोग का उपयोग करता है कि विगेट्स की तरह है, तो उन्हें अपने खुद के आवेदन में उपयोग करने के लिए स्वतंत्र महसूस हो रहा है! वे सभी django.contrib.admin.widgets में संग्रहीत हैं।

कौन सा जावास्क्रिप्ट टूलकिट?

कई जावास्क्रिप्ट टूलकिट मौजूद हैं, और उनमें से कई में विजेट्स (जैसे कैलेंडर विजेट) शामिल हैं जिनका उपयोग आपके एप्लिकेशन को बढ़ाने के लिए किया जा सकता है। Django ने जानबूझकर किसी एक जावास्क्रिप्ट टूलकिट को आशीर्वाद देने से परहेज किया है। प्रत्येक टूलकिट की अपनी रिश्तेदार ताकत और कमजोरियां होती हैं - जो भी टूलकिट आपकी आवश्यकताओं के अनुरूप उपयोग करें। Django किसी भी जावास्क्रिप्ट टूलकिट के साथ एकीकृत करने में सक्षम है।

एक स्थिर परिभाषा के रूप में संपत्ति

परिसंपत्तियों को परिभाषित करने का सबसे आसान तरीका एक स्थिर परिभाषा है। इस पद्धति का उपयोग करते हुए, घोषणा एक आंतरिक Media वर्ग है। आंतरिक वर्ग के गुण आवश्यकताओं को परिभाषित करते हैं।

यहाँ एक सरल उदाहरण दिया गया है:

from django import forms

class CalendarWidget(forms.TextInput):
    class Media:
        css = {
            'all': ('pretty.css',)
        }
        js = ('animations.js', 'actions.js')

यह कोड एक CalendarWidget को परिभाषित करता है, जो TextInput पर आधारित होगा। जब भी pretty.css का उपयोग किसी प्रपत्र पर किया जाता है, तो उस प्रपत्र को CSS फ़ाइल pretty.css और जावास्क्रिप्ट फ़ाइलों को शामिल करने के लिए निर्देशित किया जाएगा।

यह स्थिर परिभाषा रनटाइम में media नाम की विजेट संपत्ति में परिवर्तित हो जाती है। CalendarWidget उदाहरण के लिए संपत्ति की सूची इस संपत्ति के माध्यम से प्राप्त की जा सकती है:

>>> w = CalendarWidget()
>>> print(w.media)
<link href="http://static.example.com/pretty.css" type="text/css" media="all" rel="stylesheet">
<script type="text/javascript" src="http://static.example.com/animations.js"></script>
<script type="text/javascript" src="http://static.example.com/actions.js"></script>

यहां सभी संभावित Media विकल्पों की एक सूची दी गई है। कोई आवश्यक विकल्प नहीं हैं।

css

आउटपुट मीडिया के विभिन्न रूपों के लिए आवश्यक CSS फाइलों का वर्णन करने वाला शब्दकोश।

शब्दकोश में मान टपल / फ़ाइल नामों की सूची होना चाहिए। इन फ़ाइलों को पथ निर्दिष्ट करने के तरीके के विवरण के लिए पथों पर अनुभाग देखें।

शब्दकोश में चाबियाँ आउटपुट मीडिया प्रकार हैं। मीडिया घोषणाओं में CSS फाइलों द्वारा स्वीकार किए गए ये एक ही प्रकार हैं: 'all', 'aural', 'braille', 'उभरा', 'handheld', 'print', 'प्रोजेक्शन', 'स्क्रीन', 'tty' और ' टीवी '। यदि आपको अलग-अलग मीडिया प्रकारों के लिए अलग-अलग स्टाइलशीट रखने की आवश्यकता है, तो प्रत्येक आउटपुट माध्यम के लिए सीएसएस फ़ाइलों की एक सूची प्रदान करें। निम्न उदाहरण दो सीएसएस विकल्प प्रदान करेगा - एक स्क्रीन के लिए, और एक प्रिंट के लिए:

class Media:
    css = {
        'screen': ('pretty.css',),
        'print': ('newspaper.css',)
    }

यदि सीएसएस फाइलों का एक समूह कई आउटपुट मीडिया प्रकारों के लिए उपयुक्त है, तो शब्दकोश कुंजी आउटपुट मीडिया प्रकारों की अल्पविराम से अलग सूची हो सकती है। निम्नलिखित उदाहरण में, टीवी और प्रोजेक्टर की समान मीडिया आवश्यकताएं होंगी:

class Media:
    css = {
        'screen': ('pretty.css',),
        'tv,projector': ('lo_res.css',),
        'print': ('newspaper.css',)
    }

यदि इस अंतिम सीएसएस परिभाषा का प्रतिपादन किया जाना था, तो यह निम्नलिखित HTML बन जाएगी:

<link href="http://static.example.com/pretty.css" type="text/css" media="screen" rel="stylesheet">
<link href="http://static.example.com/lo_res.css" type="text/css" media="tv,projector" rel="stylesheet">
<link href="http://static.example.com/newspaper.css" type="text/css" media="print" rel="stylesheet">

js

एक जावास्क्रिप्ट आवश्यक जावास्क्रिप्ट फ़ाइलों का वर्णन। इन फ़ाइलों को पथ निर्दिष्ट करने के तरीके के विवरण के लिए पथों पर अनुभाग देखें।

extend

Media घोषणाओं के लिए विरासत व्यवहार को परिभाषित करने वाला एक बूलियन।

डिफ़ॉल्ट रूप से, स्थैतिक Media परिभाषा का उपयोग करने वाली कोई भी वस्तु पैरेंट विजेट से जुड़ी सभी संपत्तियों को प्राप्त कर लेगी। यह इस बात की परवाह किए बिना होता है कि माता-पिता अपनी आवश्यकताओं को कैसे परिभाषित करते हैं। उदाहरण के लिए, यदि हम ऊपर के उदाहरण से अपने मूल कैलेंडर विजेट का विस्तार करते हैं:

>>> class FancyCalendarWidget(CalendarWidget):
...     class Media:
...         css = {
...             'all': ('fancy.css',)
...         }
...         js = ('whizbang.js',)

>>> w = FancyCalendarWidget()
>>> print(w.media)
<link href="http://static.example.com/pretty.css" type="text/css" media="all" rel="stylesheet">
<link href="http://static.example.com/fancy.css" type="text/css" media="all" rel="stylesheet">
<script type="text/javascript" src="http://static.example.com/animations.js"></script>
<script type="text/javascript" src="http://static.example.com/actions.js"></script>
<script type="text/javascript" src="http://static.example.com/whizbang.js"></script>

FancyCalendar विजेट अपने पैरेंट विजेट से सभी परिसंपत्तियों को प्राप्त करता है। यदि आप नहीं चाहते कि Media को इस तरह विरासत में मिले, तो Media घोषणा में एक extend=False घोषणा जोड़ें:

>>> class FancyCalendarWidget(CalendarWidget):
...     class Media:
...         extend = False
...         css = {
...             'all': ('fancy.css',)
...         }
...         js = ('whizbang.js',)

>>> w = FancyCalendarWidget()
>>> print(w.media)
<link href="http://static.example.com/fancy.css" type="text/css" media="all" rel="stylesheet">
<script type="text/javascript" src="http://static.example.com/whizbang.js"></script>

यदि आपको विरासत पर और भी अधिक नियंत्रण की आवश्यकता है, तो अपनी संपत्ति को एक गतिशील संपत्ति का उपयोग करके परिभाषित करें। डायनेमिक गुण आपको पूरा नियंत्रण देते हैं कि कौन सी फाइलें विरासत में मिली हैं, और कौन सी नहीं हैं।

Media एक गतिशील संपत्ति के रूप में

यदि आपको परिसंपत्तियों की आवश्यकताओं के कुछ और अधिक परिष्कृत हेरफेर करने की आवश्यकता है, तो आप सीधे media संपत्ति को परिभाषित कर सकते हैं। यह एक विजेट संपत्ति को परिभाषित करने के द्वारा किया जाता है जो forms.Media की एक आवृत्ति लौटाता है forms.Mediaforms.Media लिए forms.Media एक ही प्रारूप में css और js कीवर्ड दलीलों को स्वीकार करता है जो एक स्थिर मीडिया परिभाषा में उपयोग किया जाता है।

उदाहरण के लिए, हमारे कैलेंडर विजेट के लिए स्थिर परिभाषा को एक गतिशील फैशन में भी परिभाषित किया जा सकता है:

class CalendarWidget(forms.TextInput):
    @property
    def media(self):
        return forms.Media(css={'all': ('pretty.css',)},
                           js=('animations.js', 'actions.js'))

डायनेमिक media गुणों के लिए वापसी मान का निर्माण करने के तरीके के बारे में अधिक जानकारी के लिए मीडिया ऑब्जेक्ट पर अनुभाग देखें।

संपत्ति परिभाषाओं में पथ

संपत्ति निर्दिष्ट करने के लिए उपयोग किए जाने वाले पथ या तो सापेक्ष या निरपेक्ष हो सकते हैं। यदि कोई पथ / , http:// या https:// साथ शुरू होता है, तो इसे एक निरपेक्ष पथ के रूप में व्याख्या किया जाएगा, और इस तरह छोड़ दिया जाएगा। अन्य सभी रास्तों को उपयुक्त उपसर्ग के मान के साथ जोड़ा जाएगा। यदि django.contrib.staticfiles ऐप स्थापित है, तो इसका उपयोग परिसंपत्तियों की सेवा के लिए किया जाएगा।

आप django.contrib.staticfiles उपयोग करते हैं या नहीं, STATIC_URL और STATIC_ROOT सेटिंग्स को एक संपूर्ण वेब पेज रेंडर करने के लिए आवश्यक है।

उपयोग करने के लिए उपयुक्त उपसर्ग खोजने के लिए, Django जाँच करेगा कि क्या STATIC_URL सेटिंग कोई None और स्वचालित रूप से MEDIA_URL का उपयोग करने के लिए वापस गिर गया। उदाहरण के लिए, यदि आपकी साइट के लिए MEDIA_URL 'http://uploads.example.com/' और STATIC_URL None :

>>> from django import forms
>>> class CalendarWidget(forms.TextInput):
...     class Media:
...         css = {
...             'all': ('/css/pretty.css',),
...         }
...         js = ('animations.js', 'http://othersite.com/actions.js')

>>> w = CalendarWidget()
>>> print(w.media)
<link href="/css/pretty.css" type="text/css" media="all" rel="stylesheet">
<script type="text/javascript" src="http://uploads.example.com/animations.js"></script>
<script type="text/javascript" src="http://othersite.com/actions.js"></script>

लेकिन अगर STATIC_URL 'http://static.example.com/' :

>>> w = CalendarWidget()
>>> print(w.media)
<link href="/css/pretty.css" type="text/css" media="all" rel="stylesheet">
<script type="text/javascript" src="http://static.example.com/animations.js"></script>
<script type="text/javascript" src="http://othersite.com/actions.js"></script>

या यदि ManifestStaticFilesStorage का उपयोग करके django.contrib.staticfiles को कॉन्फ़िगर किया गया है:

>>> w = CalendarWidget()
>>> print(w.media)
<link href="/css/pretty.css" type="text/css" media="all" rel="stylesheet">
<script type="text/javascript" src="https://static.example.com/animations.27e20196a850.js"></script>
<script type="text/javascript" src="http://othersite.com/actions.js"></script>

Media वस्तुओं

जब आप किसी विजेट या फॉर्म के media विशेषता पर पूछताछ करते हैं, तो जो मूल्य वापस किया जाता है वह एक forms.Media है forms.Media ऑब्जेक्ट। जैसा कि हमने पहले ही देखा है, Media ऑब्जेक्ट का स्ट्रिंग प्रतिनिधित्व HTML आपके HTML पृष्ठ के <head> ब्लॉक में प्रासंगिक फ़ाइलों को शामिल करने के लिए आवश्यक है।

हालांकि, Media ऑब्जेक्ट्स में कुछ अन्य दिलचस्प गुण हैं।

संपत्तियों की सदस्यता

यदि आप केवल एक विशेष प्रकार की फाइल चाहते हैं, तो आप सबस्क्रिप्ट ऑपरेटर का उपयोग कर सकते हैं रुचि के एक माध्यम को छानने के लिए। उदाहरण के लिए:

>>> w = CalendarWidget()
>>> print(w.media)
<link href="http://static.example.com/pretty.css" type="text/css" media="all" rel="stylesheet">
<script type="text/javascript" src="http://static.example.com/animations.js"></script>
<script type="text/javascript" src="http://static.example.com/actions.js"></script>

>>> print(w.media['css'])
<link href="http://static.example.com/pretty.css" type="text/css" media="all" rel="stylesheet">

जब आप सबस्क्रिप्ट ऑपरेटर का उपयोग करते हैं, तो जो मान लौटाया जाता है वह एक नया Media ऑब्जेक्ट है - लेकिन एक जिसमें केवल ब्याज की मीडिया शामिल है।

Media वस्तुओं का मेल

Media ऑब्जेक्ट्स को भी एक साथ जोड़ा जा सकता है। जब दो Media ऑब्जेक्ट जोड़े जाते हैं, तो परिणामस्वरूप Media ऑब्जेक्ट में दोनों द्वारा निर्दिष्ट संपत्ति का संघ होता है:

>>> from django import forms
>>> class CalendarWidget(forms.TextInput):
...     class Media:
...         css = {
...             'all': ('pretty.css',)
...         }
...         js = ('animations.js', 'actions.js')

>>> class OtherWidget(forms.TextInput):
...     class Media:
...         js = ('whizbang.js',)

>>> w1 = CalendarWidget()
>>> w2 = OtherWidget()
>>> print(w1.media + w2.media)
<link href="http://static.example.com/pretty.css" type="text/css" media="all" rel="stylesheet">
<script type="text/javascript" src="http://static.example.com/animations.js"></script>
<script type="text/javascript" src="http://static.example.com/actions.js"></script>
<script type="text/javascript" src="http://static.example.com/whizbang.js"></script>

संपत्ति का आदेश

जिस क्रम में संपत्ति को DOM में डाला जाता है वह अक्सर महत्वपूर्ण होता है। उदाहरण के लिए, आपके पास एक स्क्रिप्ट हो सकती है जो jQuery पर निर्भर करती है। इसलिए, Media ऑब्जेक्ट्स के संयोजन से उस सापेक्ष क्रम को संरक्षित करने का प्रयास किया जाता है जिसमें प्रत्येक Media वर्ग में संपत्ति परिभाषित की जाती है।

उदाहरण के लिए:

>>> from django import forms
>>> class CalendarWidget(forms.TextInput):
...     class Media:
...         js = ('jQuery.js', 'calendar.js', 'noConflict.js')
>>> class TimeWidget(forms.TextInput):
...     class Media:
...         js = ('jQuery.js', 'time.js', 'noConflict.js')
>>> w1 = CalendarWidget()
>>> w2 = TimeWidget()
>>> print(w1.media + w2.media)
<script type="text/javascript" src="http://static.example.com/jQuery.js"></script>
<script type="text/javascript" src="http://static.example.com/calendar.js"></script>
<script type="text/javascript" src="http://static.example.com/time.js"></script>
<script type="text/javascript" src="http://static.example.com/noConflict.js"></script>

एक MediaOrderConflictWarning में परस्पर विरोधी आदेश परिणामों में संपत्ति के साथ Media ऑब्जेक्ट्स को MediaOrderConflictWarning

Django 2.0 में बदला:

पुराने संस्करणों में, Media ऑब्जेक्ट्स की संपत्ति को एक तरह से मर्ज किए जाने के बजाय संक्षिप्त किया जाता है जो प्रत्येक सूची में तत्वों के सापेक्ष क्रम को संरक्षित करने का प्रयास करता है।

प्रपत्रों पर Media

विजेट केवल ऐसी वस्तुएं नहीं हैं जिनकी media परिभाषा हो सकती है - प्रपत्र media को भी परिभाषित कर सकते हैं। प्रपत्रों पर media परिभाषाओं के नियम विजेट के नियमों के समान हैं: घोषणाएं स्थिर या गतिशील हो सकती हैं; उन घोषणाओं के लिए पथ और विरासत नियम बिल्कुल समान हैं।

भले ही आप media घोषणा को परिभाषित करते हों, सभी फॉर्म ऑब्जेक्ट में एक media गुण होता है। इस संपत्ति के लिए डिफ़ॉल्ट मान सभी विजेट्स के लिए media परिभाषाओं को जोड़ने का परिणाम है जो फॉर्म का हिस्सा हैं:

>>> from django import forms
>>> class ContactForm(forms.Form):
...     date = DateField(widget=CalendarWidget)
...     name = CharField(max_length=40, widget=OtherWidget)

>>> f = ContactForm()
>>> f.media
<link href="http://static.example.com/pretty.css" type="text/css" media="all" rel="stylesheet">
<script type="text/javascript" src="http://static.example.com/animations.js"></script>
<script type="text/javascript" src="http://static.example.com/actions.js"></script>
<script type="text/javascript" src="http://static.example.com/whizbang.js"></script>

यदि आप अतिरिक्त परिसंपत्तियों को फ़ॉर्म के साथ जोड़ना चाहते हैं - उदाहरण के लिए, सीएसएस फॉर्म लेआउट के लिए - बस फॉर्म में एक Media घोषणा जोड़ें:

>>> class ContactForm(forms.Form):
...     date = DateField(widget=CalendarWidget)
...     name = CharField(max_length=40, widget=OtherWidget)
...
...     class Media:
...         css = {
...             'all': ('layout.css',)
...         }

>>> f = ContactForm()
>>> f.media
<link href="http://static.example.com/pretty.css" type="text/css" media="all" rel="stylesheet">
<link href="http://static.example.com/layout.css" type="text/css" media="all" rel="stylesheet">
<script type="text/javascript" src="http://static.example.com/animations.js"></script>
<script type="text/javascript" src="http://static.example.com/actions.js"></script>
<script type="text/javascript" src="http://static.example.com/whizbang.js"></script>