Django Model()与Model.objects.create()


267

运行两个命令有什么区别:

foo = FooModel()

bar = BarModel.objects.create()

第二个方法是否立即BarModel在数据库中创建一个,而对于FooModelsave()必须显式调用该方法以将其添加到数据库中?


47
是的,那是区别。
Daniel Roseman

Answers:


247

https://docs.djangoproject.com/zh-CN/stable/topics/db/queries/#creating-objects

要在一个步骤中创建和保存对象,请使用create()方法。


3
在我看来,django文档在这一点上有点矛盾。我遇到了同样的问题,并读到“请注意,实例化模型绝不会影响您的数据库;为此,您需要save()。” docs.djangoproject.com/en/1.10/ref/models/instances/…–
Nils,

6
我认为这并不矛盾。通常在python中,您可以通过在对象名称后放置方括号来实例化对象,而不是通过create方法来实现
danidee

3
@danidee我同意这并不矛盾,但是肯定会引起误解。主要是因为在Nils的链接中,example1是“实例化”,而example2是“实例化+保存”。另外,当我想知道如何保存模型时,为什么还要参考“查询”文档?Django文档确实有很多麻烦之处。

3
@Nakamura是因为INSERT是查询?
Juanjo Conti

16

两种语法不等效,并且可能导致意外错误。这是一个显示差异的简单示例。如果您有模型:

from django.db import models

class Test(models.Model):

    added = models.DateTimeField(auto_now_add=True)

然后创建第一个对象:

foo = Test.objects.create(pk=1)

然后尝试使用相同的主键创建一个对象:

foo_duplicate = Test.objects.create(pk=1)
# returns the error:
# django.db.utils.IntegrityError: (1062, "Duplicate entry '1' for key 'PRIMARY'")

foo_duplicate = Test(pk=1).save()
# returns the error:
# django.db.utils.IntegrityError: (1048, "Column 'added' cannot be null")

因此.create()即使null=False缺少必填字段()也会创建一个对象?我正在为项目添加测试,但create结果出乎意料
Vaibhav Vishal

不,它不应该...尽管某些字段类型在Django中的作用有点怪异。例如,CharField即使null=False未设置为,如果未提供也不会引发错误:这是因为Django默认将字符串设置为空字符串,""因此从技术上讲不是这样null
Thomas Leonard

是的,我只在char字段和field字段(基本上也是char字段)方面遇到问题。现在使用obj = MyModel()obj.full_clean()
Vaibhav Vishal

10

更新15.3.2017:

我已经对此打开了Django问题,似乎已经在这里被初步接受:https : //code.djangoproject.com/ticket/27825

我的经验是,当通过Django 在引用中使用ConstructorORM)类时,1.10.5数据中可能存在一些不一致(即,创建对象的属性可能获取输入数据的类型,而不是ORM对象属性的强制类型)。 :

models

class Payment(models.Model):
     amount_cash = models.DecimalField()

some_test.py -- object.create

Class SomeTestCase:
    def generate_orm_obj(self, _constructor, base_data=None, modifiers=None):
        objs = []
        if not base_data:
            base_data = {'amount_case': 123.00}
        for modifier in modifiers:
            actual_data = deepcopy(base_data)
            actual_data.update(modifier)
            # Hacky fix,
            _obj = _constructor.objects.create(**actual_data)
            print(type(_obj.amount_cash)) # Decimal
            assert created
           objs.append(_obj)
        return objs

some_test.py -- Constructor()

Class SomeTestCase:
    def generate_orm_obj(self, _constructor, base_data=None, modifiers=None):
        objs = []
        if not base_data:
            base_data = {'amount_case': 123.00}
        for modifier in modifiers:
            actual_data = deepcopy(base_data)
            actual_data.update(modifier)
            # Hacky fix,
            _obj = _constructor(**actual_data)
            print(type(_obj.amount_cash)) # Float
            assert created
           objs.append(_obj)
        return objs

Josh Smeaton 就开发人员自己对类型转换的责任提供了一个很好的答案。请更新您的答案。
Artur Barseghyan
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.