Django Model()vs Model.objects.create()

0le*_*leg 231 python database django django-models

运行两个命令之间的区别是什么:

foo = FooModel()
Run Code Online (Sandbox Code Playgroud)

bar = BarModel.objects.create()
Run Code Online (Sandbox Code Playgroud)

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

mad*_*han 213

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

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

  • 我不认为那是矛盾的.通常在python中,通过在对象名称之后放置括号而不是通过create方法来实例化对象 (5认同)
  • @danidee我同意这并不矛盾,但是肯定会引起误解。主要是因为在Nils的链接中,example1是“实例化”,而example2是“实例化+保存”。另外,当我想知道如何保存模型时,为什么还要参考“查询”文档?Django文档确实有很多麻烦之处。 (3认同)
  • 在我看来,django文档在这一点上有点矛盾。我遇到了同样的问题,并读到“请注意,实例化模型绝不会触及您的数据库;为此,您需要save()。” https://docs.djangoproject.com/en/1.10/ref/models/instances/#creating-objects (2认同)
  • @Nakamura是因为INSERT是查询? (2认同)

小智 16

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


  1. 插入与更新

    Model.save()对数据库中的对象执行 INSERT 或 UPDATE,而Model.objects.create()只执行 INSERT。

    Model.save()

    • UPDATE如果对象的主键属性设置为评估为True

    • INSERT如果对象的主键属性未设置或 UPDATE 未更新任何内容(例如,如果主键设置为数据库中不存在的值)。


  1. 现有主键

    如果主键属性设置为一个值并且这样的主键已经存在,则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()
    
    Run Code Online (Sandbox Code Playgroud)
    1. 插入/更新到数据库 Model.save()

      physics = Subject(subject_id=1, name='Physics', max_marks=100)
      physics.save()
      math = Subject(subject_id=1, name='Math', max_marks=50)  # Case of update
      math.save()
      
      Run Code Online (Sandbox Code Playgroud)

      结果:

      Subject.objects.all().values()
      <QuerySet [{'subject_id': 1, 'name': 'Math', 'max_marks': 50}]>
      
      Run Code Online (Sandbox Code Playgroud)
    2. 插入到数据库中 Model.objects.create()

      Subject.objects.create(subject_id=1, name='Chemistry', max_marks=100)
      IntegrityError: UNIQUE constraint failed: m****t.subject_id
      
      Run Code Online (Sandbox Code Playgroud)

    说明:在示例中,math.save()执行 UPDATE(namePhysics更改为Mathmax_marks从 100 更改为 50),因为subject_id是主键并且subject_id=1已存在于数据库中。但是Subject.objects.create()引发IntegrityError,因为再次subject_id具有该值的主键1已经存在。


  1. 强制插入

    Model.save()可以Model.objects.create()通过使用force_insert=True参数来使其表现得像:Model.save(force_insert=True)


  1. 返回值

    Model.save()返回NonewhereModel.objects.create()返回模型实例即package_name.models.Model


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

摘自源代码 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
Run Code Online (Sandbox Code Playgroud)

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

  1. https://docs.djangoproject.com/en/stable/ref/models/querysets/#create

  2. https://github.com/django/django/blob/2d8dcba03aae200aaa103ec1e69f0a0038ec2f85/django/db/models/query.py#L440

  • 这比公认的答案更好、更有帮助。 (4认同)

Tho*_*ard 10

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

from django.db import models

class Test(models.Model):

    added = models.DateTimeField(auto_now_add=True)
Run Code Online (Sandbox Code Playgroud)

然后你创建了第一个对象:

foo = Test.objects.create(pk=1)
Run Code Online (Sandbox Code Playgroud)

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

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")
Run Code Online (Sandbox Code Playgroud)


Ole*_*sov 8

更新15.3.2017:

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

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

models

class Payment(models.Model):
     amount_cash = models.DecimalField()
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)


小智 6

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