from django.db import IntegrityError
def update_or_create(model, filter_kwargs, update_kwargs)
if not model.objects.filter(**filter_kwargs).update(**update_kwargs):
kwargs = filter_kwargs.copy()
kwargs.update(update_kwargs)
try:
model.objects.create(**kwargs)
except IntegrityError:
if not model.objects.filter(**filter_kwargs).update(**update_kwargs):
raise # re-raise IntegrityError
मुझे लगता है कि प्रश्न में प्रदान किया गया कोड बहुत ही प्रदर्शनकारी नहीं है: कौन मॉडल के लिए आईडी सेट करना चाहता है? चलें मान हम इस की जरूरत है, और हम एक साथ ऑपरेशन:
def thread1():
update_or_create(SomeModel, {'some_unique_field':1}, {'some_field': 1})
def thread2():
update_or_create(SomeModel, {'some_unique_field':1}, {'some_field': 2})
update_or_create
के साथ समारोह, निर्भर करता है धागा आता है, जिस पर पहले वस्तु बनाया गया और कोई अपवाद के साथ अद्यतन किया जाएगा। यह धागा सुरक्षित हो जाएगा, लेकिन स्पष्ट रूप से कम इस्तेमाल किया है: SomeModek.objects.get(some__unique_field=1).some_field
की रेस स्थिति मूल्य पर निर्भर करता है हो सकता है 1 या 2
Django एफ वस्तुओं प्रदान करता है, इसलिए हम अपने कोड का उन्नयन कर सकते हैं:
from django.db.models import F
def thread1():
update_or_create(SomeModel,
{'some_unique_field':1},
{'some_field': F('some_field') + 1})
def thread2():
update_or_create(SomeModel,
{'some_unique_field':1},
{'some_field': F('some_field') + 2})
यदि कोई अन्य प्रक्रिया ऑब्जेक्ट को दो पंक्तियों के बीच बनाती है, तो create() कॉल एक इंटीग्रिटी एरर बढ़ाएगी। आप आईडी() कॉल में आईडी सेट नहीं कर रहे हैं। – GDorn
ठीक है, आप सही है, इसे IntegrityError के बारे में परवाह करना चाहिए। कोड संपादित करेंगे। – Nik
ध्यान रखें कि आपने जो पोस्ट किया है वह पहले से ही django की क्वेरीसेट के dev संस्करण में है: https://docs.djangoproject.com/en/dev/ref/models/querysets/#update-or-create –