2009-10-16 27 views
43

मुझे आश्चर्य है, django में एक मॉडल के उदाहरण के कई क्षेत्रों को अद्यतन करने का एक मानक तरीका क्या है? ... अगर मैं कुछ क्षेत्रों के साथ एक मॉडल,django मॉडल उदाहरण के एकाधिक फ़ील्ड को कैसे अपडेट करें?

Class foomodel(models.Model): 
    field1 = models.CharField(max_length=10) 
    field2 = models.CharField(max_length=10) 
    field3 = models.CharField(max_length=10) 
    ... 

है ... और मैं दिए गए एक क्षेत्र के साथ यह दृष्टांत, और फिर एक अलग चरण में मैं शेष फ़ील्ड उपलब्ध कराना चाहते हैं, मैं कैसे कर बस एक शब्दकोश या कुंजी मूल्य पैराम पास करके ऐसा करते हैं? मुमकिन?

दूसरे शब्दों में, कहें कि मेरे पास कुछ डेटा के साथ एक शब्दकोश है जिसमें मैं उस मॉडल के उदाहरण में लिखना चाहता हूं। मॉडल उदाहरण को एक अलग चरण में तुरंत चालू कर दिया गया है और मान लें कि यह अभी तक जारी नहीं है। मैं प्रत्येक क्षेत्र के लिए foo_instance.field1 = my_data_dict['field1'] कह सकता हूं, लेकिन कुछ मुझे बताता है कि मॉडल उदाहरण पर एक विधि को कॉल करने का एक तरीका होना चाहिए जहां मैं बस एक ही समय में सभी फ़ील्ड-वैल्यू जोड़े को पास करता हूं और यह उन्हें अपडेट करता है। कुछ foo_instance.update(my_data_dict) की तरह। मुझे इस तरह की कोई भी अंतर्निहित विधियां नहीं दिखाई दे रही हैं, क्या मैं इसे याद कर रहा हूं या यह कुशलतापूर्वक कैसे किया जाता है?

मुझे एहसास है कि यह एक स्पष्ट, आरटीएम प्रकार का सवाल है, लेकिन मैंने इसे दस्तावेज़ों में नहीं देखा है।

उत्तर

93

यह __dict__ साथ गड़बड़ करने के लिए होती है, लेकिन है कि एक माता पिता के वर्ग से विरासत में मिली विशेषताओं पर लागू नहीं होगा।

आप dict वस्तु के लिए आवंटित करने के लिए अधिक पुनरावृति कर सकते हैं या तो:

for (key, value) in my_data_dict.items(): 
    setattr(obj, key, value) 

या आप सीधे एक क्वेरीसमूह से संशोधित कर सकते हैं (यह सुनिश्चित करते हुए आपकी क्वेरी केवल सेट वस्तु में आपकी रुचि है देता है):

FooModel.objects.filter(whatever="anything").update(**my_data_dict) 
+0

यह काम m2m फ़ील्ड के साथ करता है? –

24

आप इस कोशिश कर सकते:

obj.__dict__.update(my_data_dict) 
+6

का उपयोग कर अद्यतन यह विरासत में मिला विशेषताओं पर लागू नहीं होगा। –

+1

इस तथ्य के निहितार्थ क्या हैं कि यह विरासत विशेषताओं पर लागू नहीं होगा? –

+0

इसके अलावा, क्या आप __dict__ का उपयोग करके विदेशीकी को अपडेट करने का प्रयास कर रहे हैं, संबंधित मान नाम 'field_name_id'' field_name' नहीं हैं, आपको इसके साथ सावधान रहना होगा। – levi

3

ऐसा लगता है कि आप ऐसी प्राकृतिक चीज की तरह हैं जो आप करना चाहते हैं लेकिन आपके जैसे ही मुझे इसे दस्तावेज़ों में नहीं मिला है। दस्तावेज़ कहते हैं कि आपको मॉडल पर सब-क्लास सेव() चाहिए। और यही वह है जो मैं करता हूं।

def save(self, **kwargs): 
    mfields = iter(self._meta.fields) 
    mods = [(f.attname, kwargs[f.attname]) for f in mfields if f.attname in kwargs] 
    for fname, fval in mods: setattr(self, fname, fval) 
    super(MyModel, self).save() 
+1

मॉडलों के लिए एक सजावटी बनाने की सोच जो अगली बार उपरोक्त शरीर के साथ "dict_save" (इसलिए मॉडल के लिए 2 सहेजने के तरीकों - सामान्य और निर्देश) को जोड़ता है। मैंने उस कोड को देखा जो मैंने ऐसा करने के लिए किया था और यह वही है, सिवाय इसके कि मैं इसे बचाने के बाहर कर रहा था।उपर्युक्त वही शरीर के साथ एक विधि update_model_obj_from_dict (model_object, update_dict) था और उम्मीद थी कि मैं कब सहेजना होगा() के बाद कॉल करना होगा। मुझे पसंद पसंद है। इसलिए शायद अंतिम पंक्ति को छोड़कर और बाद में सहेजने के बाद उपरोक्त सब कुछ के साथ "set_from_dict" नामक मॉडल पर एक विधि। – Purrell

2

मैं प्राथमिक कुंजी का नाम मिलता है, इसका इस्तेमाल Queryset.filter() और Queryset.update() साथ अद्यतन के साथ फिल्टर करने के लिए।

fooinstance = ...  
# Find primary key and make a dict for filter 
pk_name foomodel._meta.pk.name 
filtr = {pk_name: getattr(fooinstance, pk_name)} 
# Create a dict attribute to update 
updat = {'name': 'foo', 'lastname': 'bar'} 
# Apply 
foomodel.objects.filter(**filtr).update(**updat) 

इससे मुझे प्राथमिक कुंजी जो भी एक उदाहरण अपडेट करने की अनुमति मिलती है।

1

update()

Discussion.objects.filter(slug=d.slug) 
    .update(title=form_data['title'], 
      category=get_object_or_404(Category, pk=form_data['category']), 
      description=form_data['description'], closed=True) 
+0

एसओ में आपका स्वागत है। उत्तर पोस्ट करते समय कृपया अपने कोड का स्पष्टीकरण शामिल करें और टेक्स्ट को प्रारूपित करना याद रखें। – Tony

संबंधित मुद्दे