如何使用字典更新Django模型中的字段?

时间:2011-03-31 17:35:39

标签: python database django

假设我有这样的模型:

class Book(models.Model):
    num_pages = ...
    author = ...
    date = ...

我可以创建一个字典,然后使用它插入或更新模型吗?

d = {"num_pages":40, author:"Jack", date:"3324"}

5 个答案:

答案 0 :(得分:85)

以下是使用词典d创建的示例:

Book.objects.create(**d)

要更新现有模型,您需要使用QuerySet filter方法。假设您知道要更新的图书的pk

Book.objects.filter(pk=pk).update(**d)

答案 1 :(得分:48)

如果您知道要创建它:

Book.objects.create(**d)

假设您需要检查现有实例,可以使用get或create:

找到它
instance, created = Book.objects.get_or_create(slug=slug, defaults=d)
if not created:
    for attr, value in d.iteritems(): 
        setattr(instance, attr, value)
    instance.save()

正如在另一个答案中所提到的,你也可以使用查询集管理器上的update函数,但我相信它不会发出任何信号(如果你不使用它们可能对你不重要) 。但是,您可能不应该使用它来更改单个对象:

Book.objects.filter(id=id).update()

答案 2 :(得分:34)

使用**创建新模型。循环遍历字典并使用setattr()以更新现有模型。

来自汤姆克里斯蒂的Django休息框架

https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/serializers.py

for attr, value in validated_data.items():
    setattr(instance, attr, value)
instance.save()

答案 3 :(得分:1)

如果您已经有了Django对象,并且想要更新它的字段,则可以不使用过滤器来执行。因为您已经拥有了,在这种情况下,可能会:

your_obj.__dict__update(your_dict)
your_obj.save()

答案 4 :(得分:0)

除了其他答案之外,还有一个更安全的版本,可避免弄乱相关字段:

def is_simple_editable_field(field):
    return (
            field.editable
            and not field.primary_key
            and not isinstance(field, (ForeignObjectRel, RelatedField))
    )

def update_from_dict(instance, attrs, commit):
    allowed_field_names = {
        f.name for f in instance._meta.get_fields()
        if is_simple_editable_field(f)
    }

    for attr, val in attrs.items():
        if attr in allowed_field_names:
            setattr(instance, attr, val)

    if commit:
        instance.save()

它会检查您要更新的字段是否可编辑,不是主键,也不是相关字段之一。

用法示例:

book = Book.objects.first()
update_from_dict(book, {"num_pages":40, author:"Jack", date:"3324"})

豪华的DRF序列化器.create.update方法具有有限的经过验证的字段集,而不是手动更新的情况。