Django मॉडल () बनाम Model.objects.create ()


267

दो कमांड चलाने के बीच क्या अंतर है:

foo = FooModel()

तथा

bar = BarModel.objects.create()

क्या दूसरा तुरंत BarModelडेटाबेस में एक बनाता है , जबकि इसके लिए FooModel, save()विधि को डेटाबेस में जोड़ने के लिए स्पष्ट रूप से बुलाया जाना चाहिए?


47
हां, यही अंतर है।
डैनियल रोज़मैन

जवाबों:


247

https://docs.djangoproject.com/en/stable/topics/db/queries/#creating-objects

किसी एकल चरण में किसी ऑब्जेक्ट को बनाने और सहेजने के लिए, create()विधि का उपयोग करें ।


3
मेरी राय में इस बिंदु पर django डॉक्स थोड़ा विरोधाभासी हैं। मेरे पास एक ही सवाल है और पढ़ें "ध्यान दें कि किसी भी तरह से एक मॉडल को तत्काल अपने डेटाबेस को छूता है; इसके लिए, आपको () को बचाने की आवश्यकता है।" docs.djangoproject.com/en/1.10/ref/models/instances/…
निल्स

6
मैं उस विरोधाभासी के रूप में नहीं देखता। आम तौर पर अजगर में, आप ऑब्जेक्ट बनाने के बाद कोष्ठक लगाकर वस्तुओं का नामकरण नहीं करते हैं
danidee

3
@danidee मैं मानता हूं कि यह विरोधाभासी नहीं है, लेकिन यह निश्चित रूप से भ्रामक है। मुख्य रूप से क्योंकि Nils के लिंक में, example1 "Instantiating" है, लेकिन example2 "Instantiating + save" है। इसके अलावा, मुझे "क्वेरी" का उल्लेख क्यों करना चाहिए जब मैं जानना चाहता हूं कि किसी मॉडल को कैसे बचाया जाए? वास्तव में django doc में बहुत सारे दर्द हैं।
नाकामुरा

3
@ नाकामुरा क्योंकि INSERT एक क्वेरी है?
जुआनजो कोंटी

16

दो वाक्यविन्यास समतुल्य नहीं हैं और इससे अप्रत्याशित त्रुटियां हो सकती हैं। यहाँ एक सरल उदाहरण है जो अंतर दिखा रहा है। यदि आपके पास एक मॉडल है:

from django.db import models

class Test(models.Model):

    added = models.DateTimeField(auto_now_add=True)

और आप एक पहली वस्तु बनाते हैं:

foo = Test.objects.create(pk=1)

फिर आप उसी प्राथमिक कुंजी के साथ एक ऑब्जेक्ट बनाने की कोशिश करते हैं:

foo_duplicate = Test.objects.create(pk=1)
# returns the error:
# django.db.utils.IntegrityError: (1062, "Duplicate entry '1' for key 'PRIMARY'")

foo_duplicate = Test(pk=1).save()
# returns the error:
# django.db.utils.IntegrityError: (1048, "Column 'added' cannot be null")

तो .create()एक वस्तु भी बनाता है भले ही एक आवश्यक फ़ील्ड ( null=False) गायब हो? मैं अपनी परियोजना में परीक्षण जोड़ रहा हूं और createअप्रत्याशित परिणाम हो रहे हैं
वैभव विशाल

नहीं, यह नहीं करना चाहिए ... हालांकि कुछ क्षेत्र प्रकार Django में थोड़ा अजीब कार्य करते हैं। उदाहरण के लिए, CharFieldयहां तक ​​कि अगर सेट null=Falseप्रदान नहीं किया गया है तो एक त्रुटि नहीं उठाएगा: ऐसा इसलिए है क्योंकि Django सेट को डिफ़ॉल्ट रूप से एक खाली स्ट्रिंग ""null
थॉमस लियोनार्ड

हाँ, मुझे केवल चार क्षेत्रों और फ़ील्ड फ़ील्ड (जो मूल रूप से चार फ़ील्ड भी हैं) के साथ समस्याएँ हो रही हैं। उपयोग कर रहे हैं obj = MyModel(), तो obj.full_clean()अभी के लिए।
वैभव विशाल

10

अद्यतन 15.3.2017:

मैंने इस पर एक Django- मुद्दा खोला है और यह यहां प्रारंभिक रूप से स्वीकार किया गया लगता है: https://code.djangoproject.com/ticket/27825

मेरा अनुभव यह है कि Django के संदर्भ में Constructor( ORM) वर्ग का उपयोग करते समय 1.10.5डेटा में कुछ विसंगतियां हो सकती हैं (यानी बनाई गई ऑब्जेक्ट की विशेषताओं को ORM ऑब्जेक्ट प्रॉपर्टी के डाले गए प्रकार के बजाय इनपुट डेटा का प्रकार मिल सकता है) उदाहरण :

models

class Payment(models.Model):
     amount_cash = models.DecimalField()

some_test.py - object.create

Class SomeTestCase:
    def generate_orm_obj(self, _constructor, base_data=None, modifiers=None):
        objs = []
        if not base_data:
            base_data = {'amount_case': 123.00}
        for modifier in modifiers:
            actual_data = deepcopy(base_data)
            actual_data.update(modifier)
            # Hacky fix,
            _obj = _constructor.objects.create(**actual_data)
            print(type(_obj.amount_cash)) # Decimal
            assert created
           objs.append(_obj)
        return objs

some_test.py - Constructor()

Class SomeTestCase:
    def generate_orm_obj(self, _constructor, base_data=None, modifiers=None):
        objs = []
        if not base_data:
            base_data = {'amount_case': 123.00}
        for modifier in modifiers:
            actual_data = deepcopy(base_data)
            actual_data.update(modifier)
            # Hacky fix,
            _obj = _constructor(**actual_data)
            print(type(_obj.amount_cash)) # Float
            assert created
           objs.append(_obj)
        return objs

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