How to update multiple fields of a django model instance?
我想知道,在Django更新模型实例的多个字段的标准方法是什么?…如果我有一些领域的模型,
1 2 3 4 5 | Class foomodel(models.Model): field1 = models.CharField(max_length=10) field2 = models.CharField(max_length=10) field3 = models.CharField(max_length=10) ... |
…我用给定的一个字段实例化它,然后在一个单独的步骤中,我想提供其余的字段,如何通过传递字典或键值参数来实现这一点呢?可能吗?
换言之,假设我有一个字典,其中包含一些数据,其中包含我想要写入该模型实例的所有内容。模型实例已在单独的步骤中实例化,我们假设它尚未持久化。我可以对每个字段说
我觉得这是一个很明显的RTM问题,但我在医生那里没有看到。
很容易与
您可以循环访问要分配给对象的dict:
1 2 | for (key, value) in my_data_dict.items(): setattr(obj, key, value) |
或者您可以直接从查询集修改它(确保您的查询集只返回您感兴趣的对象):
1 | FooModel.objects.filter(whatever="anything").update(**my_data_dict) |
你可以试试这个:
1 | obj.__dict__.update(my_data_dict) |
这似乎是一件很自然的事情,你想做,但像你一样,我也没有在医生那里找到它。文档确实指出应该在模型上使用子类save()。我就是这么做的。
1 2 3 4 5 | 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 2 3 4 5 6 7 8 | 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 2 3 4 | 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) |