ChatGPT解决这个技术问题 Extra ChatGPT

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

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

foo = FooModel()

bar = BarModel.objects.create()

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

是的,这就是区别。
它总是真实的吗?我在 Django 文档中看到了他们在通过 *.objects.create() 创建实例后在实例上调用 save() 的地方。喜欢这里docs.djangoproject.com/en/3.1/topics/db/models/…

p
phoenix

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

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


在我看来,django 文档在这一点上有点矛盾。我有同样的问题并阅读了“请注意,实例化模型绝不会触及您的数据库;为此,您需要保存()。” docs.djangoproject.com/en/1.10/ref/models/instances/…
我不认为这是矛盾的。通常在python中,您通过在对象名称后放置方括号而不是通过创建方法来实例化对象
@danidee 我同意这并不矛盾,但肯定会产生误导。主要是因为在 Nils 的链接中,example1 是“实例化”,但 example2 是“实例化+保存”。另外,当我想知道如何保存模型时,为什么要参考“查询”文档? django doc 真的有很多痛苦。
@Nakamura 因为 INSERT 是一个查询?
@madzohan 我认为文档更改为完全相反:“要创建一个对象,请使用模型类的关键字参数对其进行实例化,然后调用 save() 将其保存到数据库中。”
S
SergiyKolesnikov

Model()Model.objects.create() 之间的区别如下:

INSERT 与 UPDATE Model.save() 对数据库中的对象执行 INSERT 或 UPDATE,而 Model.objects.create() 仅执行 INSERT。 Model.save() 执行 UPDATE 如果对象的主键属性设置为计算结果为 True INSERT 如果对象的主键属性未设置或 UPDATE 没有更新任何内容(例如,如果主键设置为数据库中不存在的值)。

现有主键 如果主键属性设置为一个值并且这样的主键已经存在,则 Model.save() 执行 UPDATE,但 Model.objects.create() 会引发 IntegrityError。考虑以下 models.py: class Subject(models.Model): subject_id = models.PositiveIntegerField(primary_key=True, db_column='subject_id') name = models.CharField(max_length=255) max_marks = models.PositiveIntegerField() Insert/使用 Model.save() 更新到 db 物理 = Subject(subject_id=1, name='Physics', max_marks=100) Physics.save() math = Subject(subject_id=1, name='Math', max_marks=50) # 更新 math.save() Result: Subject.objects.all().values() 插入到db with Model.objects.create() Subject.objects.create(subject_id=1, name='Chemistry', max_marks=100) IntegrityError: UNIQUE constraint failed: m****t.subject_id 说明:在示例中,数学.save() 执行更新(将名称从 Physics 更改为 Math,并将 max_marks 从 100 更改为 50),因为 subject_id 是主键并且 subject_id=1 已经存在于数据库中。但是 Subject.objects.create() 会引发 IntegrityError,因为值 1 的主键 subject_id 已经存在。

通过使用 force_insert=True 参数,可以使强制插入 Model.save() 表现为 Model.objects.create():Model.save(force_insert=True)。

返回值 Model.save() 返回 None 其中 Model.objects.create() 返回模型实例,即 package_name.models.Model

结论: Model.objects.create() 进行模型初始化并使用 force_insert=True 执行 save()

摘自Model.objects.create()的源代码

def create(self, **kwargs):
    """
    Create a new object with the given kwargs, saving it to the database
    and returning the created object.
    """
    obj = self.model(**kwargs)
    self._for_write = True
    obj.save(force_insert=True, using=self.db)
    return obj

有关更多详细信息,请访问以下链接:

https://docs.djangoproject.com/en/stable/ref/models/querysets/#create https://github.com/django/django/blob/2d8dcba03aae200aaa103ec1e69f0a0038ec2f85/django/db/models/query.py#L440


这比公认的答案要好得多,也更有帮助。
T
Thomas Leonard

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

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")

即使缺少必填字段 (null=False),.create() 也会创建一个对象?我正在向我的项目添加测试,create 出现意外结果
不,它不应该……尽管某些字段类型在 Django 中表现得有些奇怪。例如,CharField 即使设置为 null=False,如果未提供也不会引发错误:这是因为 Django 将字符串默认设置为空字符串 "",因此在技术上它不是 null
是的,我只遇到 char 字段和 field 字段(基本上也是 char 字段)的问题。现在使用 obj = MyModel(),然后使用 obj.full_clean()
O
Oleg Belousov

2017 年 3 月 15 日更新:

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

我的经验是,当通过 Django 1.10.5 引用使用 Constructor (ORM) 类时,数据中可能存在一些不一致(即创建的对象的属性可能获取输入数据的类型而不是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 就开发人员自己的类型转换责任给出了excellent answer。请更新您的答案。
M
Madhav Dhungana

Model.objects.create() 创建一个模型实例并保存它。 Model() 仅创建内存模型实例。在调用实例的 save() 方法保存它之前,它不会保存到数据库中。这也是验证发生的时候。