วิธีที่ถูกต้องในการใช้ get_or_create?


203

ฉันพยายามใช้ get_or_create สำหรับบางฟิลด์ในแบบฟอร์มของฉัน แต่ฉันได้รับข้อผิดพลาด 500 เมื่อฉันพยายามทำเช่นนั้น

หนึ่งในบรรทัดมีลักษณะดังนี้:

customer.source = Source.objects.get_or_create(name="Website")

ข้อผิดพลาดที่ฉันได้รับจากโค้ดด้านบนคือ:

Cannot assign "(<Source: Website>, False)": "Customer.source" 
   must be a "Source" instance.

คำตอบ:


353

จากเอกสารget_or_create :

# get_or_create() a person with similar first names.

p, created = Person.objects.get_or_create(
    first_name='John',
    last_name='Lennon',
    defaults={'birthday': date(1940, 10, 9)},
)

# get_or_create() didn't have to create an object.
>>> created
False

คำอธิบาย:defaultsช่องที่จะต้องได้รับการประเมินสำหรับความคล้ายคลึงกันได้ที่จะกล่าวถึงข้างนอก defaultsส่วนที่เหลือของเขตจะต้องมีการรวมอยู่ใน ในกรณีที่เกิดเหตุการณ์ CREATE ฟิลด์ทั้งหมดจะถูกนำมาพิจารณา

ดูเหมือนว่าคุณจะต้องกลับสู่ tuple แทนที่จะเป็นตัวแปรเดียวให้ทำดังนี้:

customer.source,created = Source.objects.get_or_create(name="Website")

3
FYI ที่สร้างขึ้นเป็นบูลีน จริงถ้าสร้างขึ้นเท็จถ้ามีการดึง
Josh

3
เพิ่มเติมsave()ซ้ำซ้อน?
zypro

@zypro มันเหมือนcreate()สร้างวัตถุและบันทึกมันทั้งหมดในขั้นตอนเดียวและไม่จำเป็นต้องมีsave()
Amin Mir

32

get_or_create ส่งคืน tuple

customer.source, created = Source.objects.get_or_create(name="Website")

16
หรือถ้าคุณไม่สนใจเกี่ยวกับธงบูล:customer.source = Source.objects.get_or_create(name="Website")[0]
mipadi

7
@Mipadi ฉันต้องการcustomer.source, _ = Source.objects.get_or_create(name="Website")เพราะมันทำให้ข้อเท็จจริงที่ว่า tuple ถูกส่งกลับชัดเจนขึ้นช่วยหลีกเลี่ยงข้อบกพร่องในอนาคต
โซโลมอน Ucko

15

get_or_create() คืนค่า tuple:

customer.source, created  = Source.objects.get_or_create(name="Website")
  • created มีค่าบูลีนถูกสร้างขึ้นหรือไม่

  • customer.source มีเป้าหมายของget_or_create()วิธีการ


12

ต่อไปนี้ @Tobu คำตอบและความคิดเห็น @mipadi ในทาง pythonic เพิ่มเติมหากไม่สนใจในการสร้างธงฉันจะใช้:

customer.source, _ = Source.objects.get_or_create(name="Website")

4

get_or_createปัญหาที่คุณจะพบเป็นคุณลักษณะที่เอกสารของ

เมื่อใช้อาร์กิวเมนต์คำหลักอื่นที่ไม่ใช่ "ค่าเริ่มต้น" ค่าส่งคืนของget_or_createเป็นตัวอย่าง นั่นเป็นเหตุผลที่มันแสดงให้คุณเห็นถึงความสำคัญของค่าตอบแทน

คุณสามารถใช้customer.source = Source.objects.get_or_create(name="Website")[0]เพื่อให้ได้ค่าที่ถูกต้อง

นี่คือลิงค์สำหรับเอกสาร: http://docs.djangoproject.com/en/dev/ref/models/querysets/#get-or-create-kwargs

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.