Django: ตั้งค่าคีย์ต่างประเทศโดยใช้จำนวนเต็ม?


106

มีวิธีตั้งค่าความสัมพันธ์คีย์ต่างประเทศโดยใช้รหัสจำนวนเต็มของโมเดลหรือไม่? นี่จะเป็นไปเพื่อวัตถุประสงค์ในการเพิ่มประสิทธิภาพ

ตัวอย่างเช่นสมมติว่าฉันมีรูปแบบพนักงาน:

class Employee(models.Model):
  first_name = models.CharField(max_length=100)
  last_name = models.CharField(max_length=100)
  type = models.ForeignKey('EmployeeType')

และ

EmployeeType(models.Model):
  type = models.CharField(max_length=100)

ฉันต้องการความยืดหยุ่นในการมีประเภทพนักงานไม่ จำกัด แต่ในแอปพลิเคชันที่ปรับใช้แล้วจะมีเพียงประเภทเดียวดังนั้นฉันจึงสงสัยว่ามีวิธีฮาร์ดโค้ดรหัสและตั้งค่าความสัมพันธ์ด้วยวิธีนี้หรือไม่ วิธีนี้ฉันสามารถหลีกเลี่ยงการเรียกฐานข้อมูลเพื่อรับวัตถุ EmployeeType ก่อน

คำตอบ:


208

ใช่:

employee = Employee(first_name="Name", last_name="Name")
employee.type_id = 4
employee.save()

ForeignKeyเขตข้อมูลจะเก็บค่าไว้ในแอตทริบิวต์พร้อม_idท้ายซึ่งคุณสามารถเข้าถึงได้โดยตรงเพื่อหลีกเลี่ยงการเยี่ยมชมฐานข้อมูล

_idรุ่นของForeignKeyเป็นลักษณะที่มีประโยชน์โดยเฉพาะอย่างยิ่งของ Django หนึ่งที่ทุกคนควรรู้และการใช้งานเป็นครั้งคราวตามความเหมาะสม

ข้อแม้:

@RuneKaagaard ชี้ให้เห็นว่าemployee.typeหลังจากนั้นไม่ถูกต้องใน Django เวอร์ชันล่าสุดแม้ว่าจะโทรemployee.save()แล้วก็ตาม (มันมีค่าเก่า) แน่นอนว่าการใช้มันจะเอาชนะจุดประสงค์ของการเพิ่มประสิทธิภาพข้างต้น แต่ฉันต้องการให้ข้อความค้นหาพิเศษโดยไม่ตั้งใจไม่ถูกต้อง ดังนั้นโปรดระวังให้ใช้สิ่งนี้เมื่อคุณทำงานกับอินสแตนซ์ของคุณเสร็จแล้วเท่านั้น (เช่นemployee)


10
นี่เป็นเอกสารหรือไม่?
Scott Stafford

8
การใช้ค่าคีย์ต่างประเทศโดยตรง: docs.djangoproject.com/en/1.8/topics/db/optimization/…
Dan Oliphant

1
ฉันทดสอบสิ่งนี้กับ Django 1.7 ในวันนี้และไม่ใช่ความคิดที่ดีที่นั่น ในขณะที่ใช้งานได้และtypeฟิลด์จะถูกเขียนลงในฐานข้อมูลหากคุณเข้าถึงtypeคุณสมบัติหลังจากนั้นจะไม่สะท้อนถึงการเปลี่ยนแปลง assert(employe.type.id == 4)กล่าวว่าในรหัสนี้จะล้มเหลว
Rune Kaagaard

3
@AmichaiSchreiber ฉันเชื่อว่า Django รุ่นต่อไปจะสามารถแก้ไขปัญหานี้ได้: code.djangoproject.com/ticket/27710
Will Hardy

2
สำหรับทุกคนที่มาที่นี่ในอนาคตปัญหานี้ได้รับการแก้ไขในDjango 2.1
humcat

46

ทางเลือกที่ใช้createเพื่อสร้างอ็อบเจกต์และบันทึกลงในฐานข้อมูลในบรรทัดเดียว:

employee = Employee.objects.create(first_name='first', last_name='last', type_id=4)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.