如何更新django模型实例的多个字段?

时间:2009-10-16 07:42:03

标签: django django-models

我想知道,在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问题,但我还没有在文档中看到它。

5 个答案:

答案 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)