我想知道,在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)
这样的东西。我没有看到任何这样的内置方法,我是否错过了它或者这是如何有效地完成的?
我有一种感觉,这是一个明显的RTM问题,但我还没有在文档中看到它。
答案 0 :(得分:114)
混淆__dict__
很有诱惑力,但这不适用于从父类继承的属性。
您可以遍历dict以分配给对象:
for (key, value) in my_data_dict.items():
setattr(obj, key, value)
或者您可以直接从查询集修改它(确保您的查询集只返回您感兴趣的对象):
FooModel.objects.filter(whatever="anything").update(**my_data_dict)
答案 1 :(得分:27)
你可以试试这个:
obj.__dict__.update(my_data_dict)
答案 2 :(得分:4)
看起来你想做的事情很自然,但是我也没有在文档中找到它。文档确实说你应该在模型上对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()
答案 3 :(得分: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)
这允许我更新任何主键的实例。
答案 4 :(得分: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)