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

运行两个命令有什么不同:

foo = FooModel()

而且

bar = BarModel.objects.create()

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

316023 次浏览

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

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

更新15.3.2017:

我已经打开了一个关于这个的django问题,它似乎在这里被初步接受: https://code.djangoproject.com/ticket/27825 < / p > 我的经验是,当通过Django 1.10.5引用使用Constructor (ORM)类时,数据中可能会有一些不一致(即创建对象的属性可能会获得输入数据的类型,而不是ORM对象属性的强制转换类型) 例子:< / p >

models

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

__abc0 - __abc1

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

__abc0 - __abc1

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

这两种语法是不等价的,可能会导致意外的错误。 下面是一个简单的例子来说明它们之间的区别。 如果你有一个模型:

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

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


  1. INSERT vs UPDATE

    Model.save()对DB中的对象执行INSERT或UPDATE操作,而Model.objects.create()只执行INSERT操作。

    Model.save()确实

    • 更新如果对象的主键属性被设置为True的值

    • 插入如果对象的主键属性没有设置,或者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()
    
    1. Model.save()插入/更新db

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

      结果:

      Subject.objects.all().values()
      <QuerySet [{'subject_id': 1, 'name': 'Math', 'max_marks': 50}]>
      
    2. Model.objects.create()插入db

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

    解释:在本例中,math.save()执行一个UPDATE(将namename0更改为name1,将max_marks从100更改为50),因为subject_id是一个主键,而subject_id=1已经存在于DB中。但是Subject.objects.create()会引发IntegrityError,因为值为1的主键subject_id已经存在。


  1. < p >强行插入

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


  1. < p >返回值

    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

更多详情请点击以下链接:

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

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

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