443 Stimmen

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

Was ist der Unterschied zwischen dem Ausführen von zwei Befehlen:

foo = FooModel()

und

bar = BarModel.objects.create()

Wird beim zweiten sofort ein BarModel in der Datenbank erstellt, während bei FooModel die save()-Methode explizit aufgerufen werden muss, um es zur Datenbank hinzuzufügen?

370voto

madzohan Punkte 10661

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

Um ein Objekt in einem Schritt zu erstellen und zu speichern, verwenden Sie die create()-Methode.

67voto

Furkan Siddiqui Punkte 1202

Die Unterschiede zwischen Model() und Model.objects.create() sind wie folgt:


  1. INSERT vs UPDATE

    Model.save() führt entweder ein INSERT oder UPDATE eines Objekts in einer DB durch, während Model.objects.create() nur ein INSERT durchführt.

    Model.save() macht

    • UPDATE Wenn das primäre Schlüsselattribut des Objekts auf einen Wert gesetzt ist, der zu True ausgewertet wird

    • INSERT Wenn das primäre Schlüsselattribut nicht gesetzt ist oder wenn das UPDATE nichts aktualisiert hat (z.B. wenn der primäre Schlüssel auf einen Wert gesetzt ist, der nicht in der Datenbank existiert).


  1. Vorhandener primärer Schlüssel

    Wenn das primäre Schlüsselattribut auf einen Wert gesetzt ist und ein solcher primärer Schlüssel bereits vorhanden ist, führt Model.save() ein UPDATE durch, während Model.objects.create() einen IntegrityError auslöst.

    Betrachten Sie die folgende 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. Einfügen/Aktualisieren in die Datenbank mit Model.save()

      physics = Subject(subject_id=1, name='Physics', max_marks=100)
      physics.save()
      math = Subject(subject_id=1, name='Math', max_marks=50)  # Aktualisierungsfall
      math.save()

      Ergebnis:

      Subject.objects.all().values()
    2. Einfügen in die Datenbank mit Model.objects.create()

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

    Erklärung: Im Beispiel führt math.save() ein UPDATE durch (ändert name von Physics auf Math und max_marks von 100 auf 50), weil subject_id ein primärer Schlüssel ist und subject_id=1 bereits in der Datenbank existiert. Aber Subject.objects.create() löst einen IntegrityError aus, weil der primäre Schlüssel subject_id mit dem Wert 1 bereits existiert.


  1. Erzwungener Einfügevorgang

    Model.save() kann dazu gebracht werden, sich wie Model.objects.create() zu verhalten, indem der Parameter force_insert=True verwendet wird: Model.save(force_insert=True).


  1. Rückgabewert

    Model.save() gibt None zurück, während Model.objects.create() eine Modellinstanz zurückgibt, d.h. package_name.models.Model


Schlussfolgerung: Model.objects.create() initialisiert das Modell und führt save() mit force_insert=True durch.

Auszug aus dem Quellcode von Model.objects.create()

def create(self, **kwargs):
    """
    Ein neues Objekt mit den angegebenen kwargs erstellen, in die Datenbank speichern
    und das erstellte Objekt zurückgeben.
    """
    obj = self.model(**kwargs)
    self._for_write = True
    obj.save(force_insert=True, using=self.db)
    return obj

Weitere Details finden Sie unter den folgenden 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

24voto

Thomas Leonard Punkte 1047

Die beiden Syntaxen sind nicht äquivalent und können zu unerwarteten Fehlern führen. Hier ist ein einfaches Beispiel, das die Unterschiede zeigt. Wenn Sie ein Modell haben:

from django.db import models

class Test(models.Model):

    added = models.DateTimeField(auto_now_add=True)

Und Sie erstellen ein erstes Objekt:

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

Dann versuchen Sie, ein Objekt mit dem gleichen Primärschlüssel zu erstellen:

foo_duplicate = Test.objects.create(pk=1)
# gibt den Fehler zurück:
# django.db.utils.IntegrityError: (1062, "Duplicate entry '1' for key 'PRIMARY'")

foo_duplicate = Test(pk=1).save()
# gibt den Fehler zurück:
# django.db.utils.IntegrityError: (1048, "Column 'added' cannot be null")

14voto

Oleg Belousov Punkte 9823

UPDATE 15.3.2017:

Ich habe dazu ein Django-Problem eröffnet und es scheint hier vorläufig akzeptiert zu werden: https://code.djangoproject.com/ticket/27825

Meine Erfahrung ist, dass es bei der Verwendung der Constructor (ORM) Klasse mit Django 1.10.5 möglicherweise Unstimmigkeiten in den Daten gibt (d.h. die Attribute des erstellten Objekts können den Typ der Eingabedaten annehmen anstatt des gecasteten Typs der ORM-Objekteigenschaft) Beispiel:

models

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

some_test.py - object.create

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

Klasse 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

7voto

Madhav Dhungana Punkte 79

Model.objects.create() erstellt eine Modellinstanz und speichert sie. Model() erstellt nur eine Modellinstanz im Arbeitsspeicher. Es wird nicht in der Datenbank gespeichert, bis Sie die save() Methode der Instanz aufrufen, um sie zu speichern. Das ist auch der Zeitpunkt, an dem die Validierung erfolgt.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X