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

TIM*_*MEX 62 python database django

假设我有这样的模型:

class Book(models.Model):
    num_pages = ...
    author = ...
    date = ...
Run Code Online (Sandbox Code Playgroud)

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

d = {"num_pages":40, author:"Jack", date:"3324"}
Run Code Online (Sandbox Code Playgroud)

Thi*_*Lam 90

这是使用你的字典d创建的一个例子:

Book.objects.create(**d)
Run Code Online (Sandbox Code Playgroud)

要更新现有模型,您需要使用QuerySet filter方法.假设您知道pk要更新的书的内容:

Book.objects.filter(pk=pk).update(**d)
Run Code Online (Sandbox Code Playgroud)

  • 我认为更新仅适用于QuerySet而不适用于单个对象. (15认同)
  • 小心:`update()`不尊重信号.请参阅下面的@leech的答案. (10认同)

lee*_*ech 50

如果您知道要创建它:

Book.objects.create(**d)
Run Code Online (Sandbox Code Playgroud)

假设您需要检查现有实例,可以使用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()
Run Code Online (Sandbox Code Playgroud)

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

Book.objects.filter(id=id).update()
Run Code Online (Sandbox Code Playgroud)

  • "不会发出任何信号":不能强调这一点. (4认同)
  • 是的,但不是为了保存。如果已创建,将有一个查找 Book (SELECT),然后另一个更新它(将生成 UPDATE 而不是 INSERT 语句)。如果这本书不存在,则可以查找 (SELECT) 并创建 (INSERT)。 (2认同)

Ign*_*ams 45

使用**用于创建一个新的模式.循环遍历字典并使用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()
Run Code Online (Sandbox Code Playgroud)

  • 很好的回答,这个电话非常明确。不是 filter(...).update(...) 的粉丝,因为弄乱过滤器会导致大量覆盖。 (2认同)

小智 8

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

your_obj.__dict__.update(your_dict)
your_obj.save()
Run Code Online (Sandbox Code Playgroud)

  • TLDR:不适用于对象字段。详细信息:如果您的字段不是像 str、int 这样的基本类型,即像 Entry 这样的对象。这是行不通的。 (5认同)