如何更新Django模型实例的多个字段?
我想知道,在Django中更新模型实例的多个字段的标准方式是什么? …如果我有一个领域的模型,
Class foomodel(models.Model): field1 = models.CharField(max_length=10) field2 = models.CharField(max_length=10) field3 = models.CharField(max_length=10) ...
…我用一个给定的字段实例化,然后在另一个步骤中,我想提供其余的字段,我怎么做只通过传递字典或键值params? 可能?
换句话说,假设我有一个包含一些数据的字典,它包含了我想要写入该模型实例的所有内容。 模型实例已经在一个单独的步骤中被实例化,并且假设它还没有被持久化。 我可以说foo_instance.field1 = my_data_dict['field1']
为每个字段,但事情告诉我应该有一种方法调用模型实例的方法,我只是通过所有的字段值对,它更新他们。 类似于foo_instance.update(my_data_dict)
。 我没有看到像这样的内置方法,我是否错过了它,或者如何有效地完成?
我有一种感觉,这是一个明显的RTMtypes的问题,但我没有看到它在文档中。
很容易__dict__
,但这不适用于从父类inheritance的属性。
您可以迭代字典来分配给对象:
for (key, value) in my_data_dict.items(): setattr(obj, key, value)
或者你可以直接从查询集中修改它(确保你的查询集只返回你感兴趣的对象):
FooModel.objects.filter(whatever="anything").update(**my_data_dict)
你可以试试这个:
obj.__dict__.update(my_data_dict)
这似乎是你想要做的自然事情,但是就像你我还没有在文档中find它。 该文档确实说你应该在模型上分类save()。 这就是我所做的。
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()
我得到主键的名字,用它来过滤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)
这使我可以更新任何主键的实例。
使用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)