How to update multiple fields of a django model instance?

I am wondering what is the standard way to update multiple fields of a model instance in django? ... If I have a model with some fields,

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

... and I create an instance with one field, and then at a separate stage I want to provide the rest of the fields, how can I do this by simply passing in the dictionary parameters or key values? Is it possible?

In other words, let's say I have a dictionary with some data in it that has everything that I want to write to an instance of this model. The model instance was created in a separate step, and let it not be preserved. I can say foo_instance.field1 = my_data_dict['field1'] for each field, but something tells me that there should be a way to call the method in the model instance, where I just pass all the pairs of field values ​​at the same time and update them. Something like foo_instance.update(my_data_dict) . I don’t see built-in methods like me, have I missed this or how is it effectively done?

I have the feeling that this is an obvious RTM question, but I just didn't see it in the docs.

+43
django django-models
Oct. 16 '09 at 7:42
source share
5 answers

It is tempting to mess with __dict__ , but this does not apply to attributes inherited from the parent class.

You can either iterate over the dict to assign to the object:

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

Or you can directly modify it from a query set (make sure your query set returns an object that interests you):

 FooModel.objects.filter(whatever="anything").update(**my_data_dict) 
+91
Sep 16 '11 at 16:17
source share

You can try the following:

 obj.__dict__.update(my_data_dict) 
+24
Oct. 16 '09 at 8:14
source share

It seems like such a natural thing that you would like to do, but like you, I also did not find it in the documents. The docs say you should use a subclass of save () for the model. And this is what I do.

 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() 
+3
Mar 23 '12 at 15:38
source share

I get the primary key name, use it to filter using Queryset.filter() and update using 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) 

This allows me to update the instance regardless of the primary key.

+2
Jul 01 '15 at 14:45
source share

Update with 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) 
+1
Mar 13 '17 at 9:22
source share



All Articles