代码之家  ›  专栏  ›  技术社区  ›  Purrell

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

  •  52
  • Purrell  · 技术社区  · 15 年前

    我想知道,在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 回复  |  直到 8 年前
        1
  •  108
  •   Wilfred Hughes AntuanSoft    13 年前

    很容易搞得一团糟 __dict__ ,但这不适用于从父类继承的属性。

    您可以循环访问要分配给对象的dict:

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

    或者您可以直接从查询集修改它(确保您的查询集只返回您感兴趣的对象):

    FooModel.objects.filter(whatever="anything").update(**my_data_dict)
    
        2
  •  25
  •   Daniel Roseman    15 年前

    你可以试试这个:

    obj.__dict__.update(my_data_dict)
    
        3
  •  3
  •   longhaulblue    13 年前

    这似乎是一件很自然的事情,你想做,但像你一样,我也没有在医生那里找到它。文档确实指出应该在模型上使用子类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()
    
        4
  •  2
  •   Zulu    9 年前

    我得到主键的名称,用它来过滤 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)
    

    这允许我更新一个实例,不管主键是什么。

        5
  •  1
  •   Tony    8 年前

    使用更新 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)