यदि मौजूद है तो Django मॉडल बनाएं या अपडेट करें


115

मैं व्यक्ति की तरह एक मॉडल ऑब्जेक्ट बनाना चाहता हूं, यदि व्यक्ति की आईडी मौजूद नहीं है, या मुझे वह व्यक्ति ऑब्जेक्ट मिलेगा।

निम्नलिखित के रूप में एक नया व्यक्ति बनाने के लिए कोड:

class Person(models.Model):
    identifier = models.CharField(max_length = 10)
    name = models.CharField(max_length = 20)
    objects = PersonManager()

class PersonManager(models.Manager):
    def create_person(self, identifier):
        person = self.create(identifier = identifier)
        return person

लेकिन मुझे नहीं पता कि मौजूदा व्यक्ति वस्तु को कहां जांचना और प्राप्त करना है।

जवाबों:


169

यदि आप "अपडेट मौजूद है तो मौजूद बनाएं" उपयोग मामले के लिए देख रहे हैं, तो कृपया @Zags उत्कृष्ट उत्तर देखें


Django में पहले से ही एक get_or_create, https://docs.djangoproject.com/en/dev/ref/models/querysets/#get-or-create है

आपके लिए यह हो सकता है:

id = 'some identifier'
person, created = Person.objects.get_or_create(identifier=id)

if created:
   # means you have created a new person
else:
   # person just refers to the existing one

मैं django 1.9 का उपयोग कर रहा हूं, और यह मुझे दे रहा है: AttractError: 'QuerySet' ऑब्जेक्ट में कोई विशेषता नहीं है 'update_or_create'
ofek Gila

1
@OfekGila स्रोत कोड और दस्तावेज़ीकरण की पुष्टि दोनों ही अजीब QuerySetहैupdate_or_create
bakkal

2
मेरे मामले में, पहचानकर्ता के स्थान पर, मेरे पास फ़ील्ड्स का समूह है, जो कि अनूठे रूप से बना है। इस मामले का उपयोग कैसे किया जाता है?
राकमो

192

यह स्पष्ट नहीं है अपने प्रश्न के लिए पूछ रहा है कि क्या है get_or_create विधि (कम से कम Django 1.3 से उपलब्ध है) या update_or_create विधि (Django 1.7 में नया)। यह निर्भर करता है कि आप उपयोगकर्ता ऑब्जेक्ट को कैसे अपडेट करना चाहते हैं।

नमूना उपयोग इस प्रकार है:

# In both cases, the call will get a person object with matching
# identifier or create one if none exists; if a person is created,
# it will be created with name equal to the value in `name`.

# In this case, if the Person already exists, its existing name is preserved
person, created = Person.objects.get_or_create(
        identifier=identifier, defaults={"name": name}
)

# In this case, if the Person already exists, its name is updated
person, created = Person.objects.update_or_create(
        identifier=identifier, defaults={"name": name}
)

12
+1 के लिए update_or_createक्योंकि उस उपयोग के मामले के लिए यह get_or_createसिर्फ save()ऑब्जेक्ट पर फिर से कॉल करने से बेहतर है ।
बक्कल

मेरे मामले में, पहचानकर्ता के स्थान पर, मेरे पास फ़ील्ड्स का समूह है, जो कि अनूठे रूप से बना है। इस मामले का उपयोग कैसे किया जाता है?
राकमो

1
@OmkarDeshpande पहचानकर्ता सिर्फ एक उदाहरण है; आप किसी भी मान्य django क्वेरी में पास कर सकते हैं, जैसेPerson.objects.get_or_create(a=a, b=b, c=c, defaults={"name": name})
Zags

क्या होगा अगर मैं डिफ़ॉल्ट व्यक्ति की तुलना में बनाए गए व्यक्ति में अधिक फ़ील्ड जोड़ना चाहता हूं?
लो बेलिन

@ बीबेलिन defaultsइन कार्यों के लिए तर्क यह है कि आप निर्दिष्ट करते हैं कि आप मॉडल में क्या फ़ील्ड जोड़ना चाहते हैं। इसका आपके मॉडल के क्षेत्रों पर निर्दिष्ट चूक से कोई लेना-देना नहीं है
Zags


4

केवल कुछ ही वस्तुओं के लिए update_or_create अच्छी तरह से काम करता है, लेकिन यदि आप एक बड़े संग्रह पर काम कर रहे हैं तो यह अच्छे पैमाने पर नहीं होगा। update_or_create हमेशा पहले एक SELECT चलाता है और उसके बाद एक अद्यतन।

for the_bar in bars:
    updated_rows = SomeModel.objects.filter(bar=the_bar).update(foo=100)
        if not updated_rows:
            # if not exists, create new
            SomeModel.objects.create(bar=the_bar, foo=100)

यह केवल पहले अपडेट-क्वेरी को चलाने के लिए सबसे अच्छा होगा, और केवल तभी जब यह शून्य पंक्तियों से मेल खाता हो, एक और INSERT- क्वेरी चलाते हैं। यदि आप वास्तव में मौजूदा पंक्तियों में से अधिकांश की अपेक्षा करते हैं तो आपके प्रदर्शन में वृद्धि होगी।

यह सब हालांकि आपके उपयोग के मामले में नीचे आता है। यदि आप ज्यादातर आवेषण की उम्मीद कर रहे हैं तो शायद बल्क_क्रिएट () कमांड एक विकल्प हो सकता है।


3

सोचा था कि मैं एक जवाब जोड़ दूंगा क्योंकि आपका प्रश्न शीर्षक ऐसा लगता है कि यह पूछ रहा है कि कैसे बनाएं या अपडेट करें, बजाय प्रश्न बॉडी में वर्णित किए गए या बनाने के लिए।

यदि आप कोई ऑब्जेक्ट बनाना या अपडेट करना चाहते हैं, तो .save () विधि में पहले से ही यह व्यवहार डिफ़ॉल्ट रूप से है , डॉक्स से :

Django को INSERT या UPDATE SQL कथनों का उपयोग करने की आवश्यकता है। विशेष रूप से, जब आप सेव कॉल करते हैं (), Django इस एल्गोरिथ्म का अनुसरण करता है:

यदि ऑब्जेक्ट की प्राथमिक कुंजी विशेषता एक मान पर सेट होती है जो True (यानी, कोई भी या रिक्त स्ट्रिंग के अलावा कोई अन्य) का मूल्यांकन करता है, तो Django एक अद्यतन निष्पादित करता है। यदि ऑब्जेक्ट की प्राथमिक कुंजी विशेषता सेट नहीं है या यदि अद्यतन कुछ अद्यतन नहीं किया है, तो Django एक INSERT निष्पादित करता है।

यह ध्यान देने योग्य है कि जब वे कहते हैं 'अगर अद्यतन कुछ भी अपडेट नहीं किया है' तो वे अनिवार्य रूप से उस मामले का उल्लेख कर रहे हैं जहां आपने जिस ऑब्जेक्ट को ऑब्जेक्ट दिया था वह डेटाबेस में पहले से मौजूद नहीं है।


1

यदि आप बनाते समय इनपुट में से एक प्राथमिक कुंजी है, तो यह पर्याप्त होगा:

Person.objects.get_or_create(id=1)

यदि एक ही प्राथमिक कुंजी के साथ दो डेटा की अनुमति नहीं है तो यह स्वतः ही अपडेट हो जाएगा।

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