Django ModelForm: क्या बचाओ (कमिट = गलत) के लिए प्रयोग किया जाता है?


88

मैं कभी भी उपवर्ग save(commit=False)से केवल एक फॉर्म ऑब्जेक्ट बनाने के बजाय उपयोग करूंगा और फॉर्म और मॉडल दोनों को मान्य करने के लिए चलूंगा?ModelFormis_valid()

दूसरे शब्दों में, क्या है save(commit=False)?

यदि आपको कोई आपत्ति नहीं है, तो क्या आप लोग काल्पनिक परिस्थितियाँ प्रदान कर सकते हैं जहाँ यह उपयोगी हो सकता है?

जवाबों:


110

यह तब उपयोगी होता है जब आप अपने मॉडल का अधिकांश डेटा एक फॉर्म से प्राप्त करते हैं, लेकिन null=Falseगैर-प्रपत्र डेटा के साथ कुछ फ़ील्ड्स को पॉप्युलेट करने की आवश्यकता होती है ।

कमेट के साथ बचत करना = गलत तरीके से आपको एक मॉडल ऑब्जेक्ट मिल जाता है, फिर आप अपना अतिरिक्त डेटा जोड़ सकते हैं और इसे बचा सकते हैं।

यह उस स्थिति का एक अच्छा उदाहरण है।


लेकिन फिर अगर यह आपको एक मॉडल ऑब्जेक्ट मिलता है, तो यह पहले से तात्कालिक ऑब्जेक्ट को असाइन करने और इसे मॉडलफ़ॉर्म को असाइन करने से अलग कैसे होता है? (यानी form = forms.SampleForm(instance = models.Sample))
ओजीजीजेंट जूल

क्या आपको जरूरत है commit=Falseअगर आप अपने फॉर्म को एक CBVसाथ प्रोसेस कर रहे हैं def form_valid? क्या आप form.instance.[field]अपडेट करने के लिए उपयोग कर सकते हैं ?
अलिसा

चलो 100 :)
दानी हेररा

39

यहाँ इसका उत्तर है ( डॉक्स से ):

# Create a form instance with POST data.
>>> f = AuthorForm(request.POST)

# Create, but don't save the new author instance.
>>> new_author = f.save(commit=False)

सबसे आम स्थिति फॉर्म से उदाहरण प्राप्त करना है लेकिन केवल 'मेमोरी में', डेटाबेस में नहीं। इसे बचाने से पहले आप कुछ बदलाव करना चाहते हैं:

# Modify the author in some way.
>>> new_author.some_field = 'some_value'

# Save the new instance.
>>> new_author.save()

1
क्या आपको जरूरत है commit=Falseअगर आप अपने फॉर्म को एक CBVसाथ प्रोसेस कर रहे हैं def form_valid? क्या आप form.instance.[field]अपडेट करने के लिए उपयोग कर सकते हैं ?
अलिसा

14

Django डॉक्स से:

यह सहेजें () विधि एक वैकल्पिक प्रतिबद्ध कीवर्ड तर्क को स्वीकार करती है, जो सही या गलत स्वीकार करता है। यदि आप कमेट = फाल्स के साथ सेव () कहते हैं, तो यह एक ऐसी वस्तु लौटाएगा जो अभी तक डेटाबेस में सेव नहीं हुई है।

इस मामले में, परिणामी मॉडल उदाहरण पर सेव () कॉल करना आपके ऊपर है। यह उपयोगी है यदि आप इसे सहेजने से पहले ऑब्जेक्ट पर कस्टम प्रसंस्करण करना चाहते हैं, या यदि आप किसी विशेष मॉडल बचत विकल्पों में से किसी एक का उपयोग करना चाहते हैं। डिफ़ॉल्ट रूप से कमिट सही है।

ऐसा लगता है कि सहेजें (प्रतिबद्ध = गलत) एक मॉडल उदाहरण बनाता है, जिसे वह आपको देता है। जो वास्तव में इसे बचाने से पहले कुछ पोस्ट प्रोसेसिंग के लिए साफ है!


10

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

class UserForm(forms.ModelForm):
    ...
    def save(self):
        # Sets username to email before saving
        user = super(UserForm, self).save(commit=False)
        user.username = user.email
        user.save()
        return user

यदि आपने commit=Falseउपयोगकर्ता नाम को ईमेल पते पर सेट करने के लिए उपयोग नहीं किया है , तो आपको या तो उपयोगकर्ता मॉडल की बचत विधि को संशोधित करना होगा, या उपयोगकर्ता ऑब्जेक्ट को दो बार सहेजना होगा (जो एक महंगा डेटाबेस ऑपरेशन को डुप्लिकेट करता है।)


क्या आपको जरूरत है commit=Falseअगर आप अपने फॉर्म को एक CBVसाथ प्रोसेस कर रहे हैं def form_valid? क्या आप form.instance.[field]अपडेट करने के लिए उपयोग कर सकते हैं ?
अलिसा

1
            form = AddAttachmentForm(request.POST, request.FILES)
            if form.is_valid():
                attachment = form.save(commit=False)
                attachment.user = student
                attachment.attacher = self.request.user
                attachment.date_attached = timezone.now()
                attachment.competency = competency
                attachment.filename = request.FILES['attachment'].name
                if attachment.filename.lower().endswith(('.png','jpg','jpeg','.ai','.bmp','.gif','.ico','.psd','.svg','.tiff','.tif')):
                    attachment.file_type = "image"
                if attachment.filename.lower().endswith(('.mp4','.mov','.3g2','.avi','.flv','.h264','.m4v','.mpg','.mpeg','.wmv')):
                    attachment.file_type = "video"
                if attachment.filename.lower().endswith(('.aif','.cda','.mid','.midi','.mp3','.mpa','.ogg','.wav','.wma','.wpl')):
                    attachment.file_type = "audio"
                if attachment.filename.lower().endswith(('.csv','.dif','.ods','.xls','.tsv','.dat','.db','.xml','.xlsx','.xlr')):
                    attachment.file_type = "spreasheet"
                if attachment.filename.lower().endswith(('.doc','.pdf','.rtf','.txt')):
                    attachment.file_type = "text"
                attachment.save()

यहां सेव (कमिट = गलत) का उपयोग करने का मेरा उदाहरण है। मैं यह जांचना चाहता था कि किसी उपयोगकर्ता ने डेटाबेस में सहेजने से पहले किस प्रकार की फ़ाइल अपलोड की थी। मैं उस तारीख को भी प्राप्त करना चाहता था जो उस क्षेत्र में संलग्न थी क्योंकि वह फॉर्म में नहीं थी।


यह एक अजगर कोड है जिसे आप इसे कोड स्निपेट में नहीं चला सकते हैं
Ayoub Benayache
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.