2012-07-29 7 views
17

स्रोत कोड से, आप देख सकते हैं कि Django 1.4 की Form कक्षा में has_changed() विधि और changed_data संपत्ति है जो उपयोगी लगता है, लेकिन यह अनौपचारिक है। मेरा प्रश्न है: उम्मीद के रूप में इन काम करते हैं, अर्थात्:Django 1.4 में, Form.has_changed() और Form.changed_data, जो अनियंत्रित हैं, अपेक्षित कार्य करते हैं?

  • Form.clean() में, Form.has_changed() रिटर्न True यदि कोई किसी भी रूप डेटा बदल गया है, अन्यथा False
  • Form.clean() में, Form.changed_data फ़ील्ड नाम जिसका मान हैं की एक सूची है बदला हुआ।

यदि हां, तो गैर-दस्तावेज सुविधाओं (यानी परिवर्तन के अधीन, समर्थित नहीं, आदि) के उपयोग के बारे में सामान्य चेतावनी/खतरों के अलावा, इसका उपयोग न करने के लिए कोई विशिष्ट कारण नहीं हैं?

नोट 1: इनके लिए कस्टम विगेट्स के साथ काम करने के लिए, उन विगेट्स को _has_changed() विधि होना चाहिए, जिसे विगेट्स में निर्मित के लिए परिभाषित किया गया है।

नोट 2: दिलचस्प बात यह है कि प्रलेखन में Formset.has_changed() विधि का अपहरण उल्लेख शामिल है, लेकिन Form.has_changed() का उल्लेख नहीं है।

+1

शानदार सुविधा। समझाने के लिए धन्यवाद। ;-) – Houman

उत्तर

23

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

तो प्रश्न यह है कि POST डेटा से बनाए गए फॉर्म को पता है कि जीईटी फॉर्म के शुरुआती मूल्य क्या थे? संक्षिप्त जवाब यह नहीं है - जब तक कि आप इसे किसी भी तरह से नहीं बताते। प्रपत्र और/या क्षेत्रों के लिए initial कीवर्ड तर्कों को

  1. वाया initial कीवर्ड तर्क, ठीक उसी तरह आपको बता GET प्रारंभिक मान के रूप में: वहाँ दो यह बताने के लिए तरीके हैं। नोट: यदि आप ऐसा करते हैं, तो यह सुनिश्चित करने के लिए आप अपने जीईटी और पोस्ट फॉर्म के लिए समान मानों का उपयोग करते हैं। ऐसा करने का यह एकमात्र सही तरीका है, क्योंकि आप सीधे प्रारंभिक मानों को नियंत्रित करते हैं।

  2. आप Django को show_hidden_initial कीवर्ड तर्क को प्रत्येक लागू फ़ील्ड के लिए True पर सेट करके अपने जीईटी से शुरुआती मूल्यों को याद रखने का काम करते हैं। इन क्षेत्रों के लिए, Django GET फॉर्म के HTML में प्रारंभिक मान के साथ एक छुपा इनपुट तत्व प्रस्तुत करता है। बाद में, जब आप पोस्ट फॉर्म पर has_changed या changed_data पर कॉल करते हैं, show_hidden_initialTrue के साथ किसी भी क्षेत्र के लिए POango स्वचालित रूप से POST डेटा में छुपा इनपुट तत्वों से शुरुआती मान प्राप्त करेगा (initial फॉर्म या फ़ील्ड तर्क से प्रारंभिक मानों का अधिग्रहण)।नोट: जैसा कि POST डेटा पर निर्भर कुछ भी है, यह दृष्टिकोण अंततः अविश्वसनीय है, क्योंकि छिपे हुए इनपुट के मान छुपाए जाने के बावजूद अभी भी बदला जा सकता है।

+1

'प्रारंभिक' कीवर्ड का उपयोग करने के तरीके पर आप विस्तार कर सकते हैं। जब आप फ़ॉर्म भेजते हैं या फॉर्म वापस आने पर इसका उपयोग करते हैं तो क्या आप इसका इस्तेमाल करते हैं? और यह 'इंस्टेंस' के साथ कैसे काम करता है? – Sevenearths

+1

@ Ghopper21 क्या आप एक कोड स्निपेट प्रदान कर सकते हैं? – andi

5

आप दो शर्तों पर उन तरीकों पर भरोसा कर सकते हैं:

  1. तुम भी पोस्ट अनुरोधों के दौरान प्रपत्र निर्माता के लिए प्रारंभिक डेटा dict गुजरती हैं।
  2. आप show_hidden_initial=True वाले फ़ील्ड का उपयोग नहीं करते हैं। (जैसे क्षेत्रों के साथ मुद्दा यह है कि एक उपयोगकर्ता की तुलना के लिए भी इस्तेमाल किया प्रारंभिक मूल्य प्रस्तुत कर सकते हैं और इस तरह के रूप में यह विश्वसनीय नहीं होगा।)
+0

धन्यवाद! यह उत्तर मेरे लिए एक और सवाल पूछता है - 'show_hidden_initial' क्या है? मैं इसे Django दस्तावेज़ों में नहीं ढूंढ सकता ... – Ghopper21

+0

'show_hidden_initial' का मतलब है कि एक दूसरा छिपे हुए फ़ील्ड को मूल HTML आउटपुट के साथ उत्पन्न किया गया है जिसमें फ़ील्ड का प्रारंभिक मान होता है। –

+0

मैं देखता हूं, धन्यवाद। – Ghopper21

0

यहां कोड का एक टुकड़ा है जो @ Ghopper21 सुझाव दे रहा है। प्रारंभिक डेटा प्राप्त करने के लिए, मैं QueryDict पर मान() फ़ंक्शन का उपयोग करता हूं। यह ऑब्जेक्ट से संबंधित डेटा युक्त एक शब्दकोश देता है। एक महत्वपूर्ण चेतावनी यह है कि मैंने यह जांच नहीं की है कि यह विदेशी कुंजी संदर्भों को कैसे प्रबंधित करता है।

saveStudentView(request,studentID): 
    existingData = Student.objects.filter(id=paperID).values()[0] 
    form = StudentForm(request.POST) 
    if form.is_valid(): 
     form = StudentForm(request.POST, initial=existingData) 
     if not form.has_changed(): 
      //Tell the user nothing has changed 
     else: 
      //Do other stuff