ความแตกต่างระหว่างการรันสองคำสั่งคืออะไร:
foo = FooModel()
และ
bar = BarModel.objects.create()
ไม่คนที่สองทันทีสร้างBarModel
ในฐานข้อมูลในขณะที่สำหรับFooModel
การsave()
วิธีการที่จะต้องมีการเรียกอย่างชัดเจนเพื่อเก็บไว้ในฐานข้อมูลหรือไม่
ความแตกต่างระหว่างการรันสองคำสั่งคืออะไร:
foo = FooModel()
และ
bar = BarModel.objects.create()
ไม่คนที่สองทันทีสร้างBarModel
ในฐานข้อมูลในขณะที่สำหรับFooModel
การsave()
วิธีการที่จะต้องมีการเรียกอย่างชัดเจนเพื่อเก็บไว้ในฐานข้อมูลหรือไม่
คำตอบ:
https://docs.djangoproject.com/en/stable/topics/db/queries/#creating-objects
ในการสร้างและบันทึกวัตถุในขั้นตอนเดียวให้ใช้
create()
วิธีการ
ไวยากรณ์ทั้งสองไม่เท่ากันและสามารถนำไปสู่ข้อผิดพลาดที่ไม่คาดคิด นี่คือตัวอย่างง่ายๆที่แสดงความแตกต่าง หากคุณมีแบบจำลอง:
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")
.create()
สร้างวัตถุแม้ว่าฟิลด์ที่จำเป็น ( null=False
) จะหายไป? ฉันกำลังเพิ่มการทดสอบในโครงการของฉันและcreate
มีผลลัพธ์ที่ไม่คาดคิด
CharField
แม้ว่าการตั้งค่าnull=False
จะไม่ทำให้เกิดข้อผิดพลาดหากไม่ได้ระบุไว้: นี่เป็นเพราะ Django ตั้งค่าสตริงโดยค่าเริ่มต้นเป็นสตริงว่าง""
ดังนั้นจึงไม่ใช่ในทางเทคนิคnull
obj = MyModel()
แล้วobj.full_clean()
ตอนนี้
อัพเดท 15.3.2017:
ฉันได้เปิด Django ฉบับนี้แล้วและดูเหมือนว่าจะเป็นที่ยอมรับเบื้องต้นที่นี่: https://code.djangoproject.com/ticket/27825
ประสบการณ์ของฉันคือเมื่อใช้คลาสConstructor
( ORM
) โดยการอ้างอิงกับ Django 1.10.5
อาจมีความไม่สอดคล้องกันในข้อมูล (เช่นคุณลักษณะของวัตถุที่สร้างขึ้นอาจได้รับประเภทของข้อมูลที่ป้อนเข้าแทนประเภท casted ของคุณสมบัติวัตถุ 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