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

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


The two syntaxes are not equivalent and it can lead to unexpected errors.Here is a simple example showing the differences.If you have a model:

from django.db import modelsclass Test(models.Model):    added = models.DateTimeField(auto_now_add=True)

And you create a first object:

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

Then you try to create an object with the same primary key:

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


The differences between Model() and Model.objects.create() are the following:


  1. INSERT vs UPDATE

    Model.save() does either INSERT or UPDATE of an object in a DB, while Model.objects.create() does only INSERT.

    Model.save() does

    • UPDATE If the object’s primary key attribute is set to a value that evaluates to True

    • INSERT If the object’s primary key attribute is not set or if the UPDATE didn’t update anything (e.g. if primary key is set to a value that doesn’t exist in the database).


  1. Existing primary key

    If primary key attribute is set to a value and such primary key already exists, then Model.save() performs UPDATE, but Model.objects.create() raises IntegrityError.

    Consider the following 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. Insert/Update to db with 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 updatemath.save()

      Result:

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

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

    Explanation: In the example, math.save() does an UPDATE (changes name from Physics to Math, and max_marks from 100 to 50), because subject_id is a primary key and subject_id=1 already exists in the DB. But Subject.objects.create() raises IntegrityError, because, again the primary key subject_id with the value 1 already exists.


  1. Forced insert

    Model.save() can be made to behave as Model.objects.create() by using force_insert=True parameter: Model.save(force_insert=True).


  1. Return value

    Model.save() return None where Model.objects.create() return model instance i.e. package_name.models.Model


Conclusion: Model.objects.create() does model initialization and performs save() with force_insert=True.

Excerpt from the source code of 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

For more details follow the links:

  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