`related_name` ใช้สำหรับอะไรใน Django


390

อะไรคือrelated_nameข้อโต้แย้งที่เป็นประโยชน์สำหรับบนManyToManyFieldและForeignKeyเขต? ตัวอย่างเช่นเมื่อได้รับรหัสต่อไปนี้จะเกิดผลrelated_name='maps'อะไร?

class Map(db.Model):
    members = models.ManyToManyField(User, related_name='maps',
                                     verbose_name=_('members'))

12
@DanielRoseman มันเป็นวิธีที่ดีสำหรับการปฏิบัติงานหรือการปฏิบัติที่ดีในการใช้ related_name = '+' เมื่อไม่จำเป็นต้องมีความสัมพันธ์ย้อนหลังหรือไม่?
lajarre

10
ฉันอยากรู้อยากเห็นรู้คำตอบสำหรับคำถามของ @ lajarre
3cheesewheel

1
@lajarre - ฉันคิดว่าจะไม่เปลี่ยนประสิทธิภาพเลย ฉันต้องใช้งานครั้งเดียวกับประเภทเนื้อหา FeinCMS ฉันคิดว่าเป็นการดีที่จะระบุไว้เสมอrelated_nameหากคุณรู้ว่าคุณจะไม่ใช้มันฉันคิดว่ามันเป็นสิ่งที่ดี นั่นเป็นความเห็นส่วนตัวแน่นอน
François Constant

@ 3cheesewheel อยู่ในเอกสารทันที: docs.djangoproject.com/en/2.0/ref/models/fields/ … +หมายความว่าอย่าสร้างความสัมพันธ์แบบย้อนกลับ
P. Myer Nore

คำตอบ:


530

related_nameแอตทริบิวต์ระบุชื่อของความสัมพันธ์กลับจากที่Userรูปแบบการกลับไปที่รูปแบบของคุณ

หากคุณไม่ได้ระบุrelated_name, Django จะสร้างขึ้นมาโดยใช้ชื่อของรูปแบบของคุณด้วยการต่อท้ายเช่น_setUser.map_set.all()

หากคุณไม่ระบุเช่นrelated_name=mapsในUserรุ่นUser.map_setจะยังคงทำงาน แต่User.maps.ไวยากรณ์จะเห็นได้ชัดทำความสะอาดบิตและ clunky น้อย; ดังนั้นสำหรับตัวอย่างเช่นถ้าคุณมีวัตถุผู้ใช้current_userคุณสามารถใช้current_user.maps.all()เพื่อให้ได้ทุกกรณีที่คุณรูปแบบที่มีความสัมพันธ์กับMapcurrent_user

เอกสาร Djangoมีรายละเอียดเพิ่มเติม


1
โอเคฉันรู้ว่านี่เป็นโพสต์เก่า แต่ฉันแค่พยายามคิดออก - เคล็ดลับ + ท้ายชื่อที่เกี่ยวข้องคืออะไร ตัวอย่างเช่นจะเกิดอะไรขึ้นถ้าฉันทำrelated_name='maps+'ในตัวอย่างด้านบน
Sidd

10
หากคุณเพิ่มเครื่องหมาย +, django จะปิดใช้งานการแมป
josephmisiti

5
สำหรับค่าเริ่มต้น OneToOneField related_name จะเป็นชื่อคลาสเคสขนาดเล็ก ตัวอย่างเช่นในตัวอย่างที่กำหนดหากสมาชิกจะเป็น OneToOnefield ดังนั้น "User.map" จะใช้งานได้
ancho

หากคุณระบุrelated_nameไม่_setยังคงทำงานในdjango1.11 >??
Esir Kings

9
ฉันใช้ Django 2.1.3 และฉันสามารถสังเกตได้ว่ามันพิเศษ เมื่อrelated_nameมีการระบุ_setไม่ทำงานอีกต่อไป
stockersky

83

เพื่อเพิ่มคำตอบชื่อที่เกี่ยวข้องที่มีอยู่จะต้องในกรณีที่มี 2 FKs ในรูปแบบที่ชี้ไปที่ตารางเดียวกัน ตัวอย่างเช่นในกรณีของรายการวัสดุ

@with_author 
class BOM(models.Model): 
    name = models.CharField(max_length=200,null=True, blank=True)
    description = models.TextField(null=True, blank=True)
    tomaterial =  models.ForeignKey(Material, related_name = 'tomaterial')
    frommaterial =  models.ForeignKey(Material, related_name = 'frommaterial')
    creation_time = models.DateTimeField(auto_now_add=True, blank=True)
    quantity = models.DecimalField(max_digits=19, decimal_places=10)

ดังนั้นเมื่อคุณจะต้องเข้าถึงข้อมูลนี้คุณสามารถใช้ชื่อที่เกี่ยวข้องเท่านั้น

 bom = material.tomaterial.all().order_by('-creation_time')

มันไม่ทำงานเป็นอย่างอื่น (อย่างน้อยฉันก็ไม่สามารถข้ามการใช้ชื่อที่เกี่ยวข้องในกรณีที่ 2 FK ของไปยังตารางเดียวกัน)


2
คุณต้องเลือกชื่อที่เกี่ยวข้องอย่างน้อยหนึ่งรายการ ส่วนอีกอันไม่จำเป็นต้องใช้
Csaba Toth

32
related_nameควรเป็นพหูพจน์ เนื่องจากความสัมพันธ์ ForeignKey ส่งคืนวัตถุหลายรายการ
Mesut Tasci

10

related_nameอาร์กิวเมนต์ยังเป็นประโยชน์ถ้าคุณมีชื่อชั้นที่เกี่ยวข้องที่ซับซ้อนมากขึ้น ตัวอย่างเช่นหากคุณมีความสัมพันธ์กับคีย์ต่างประเทศ:

class UserMapDataFrame(models.Model):
    user = models.ForeignKey(User) 

เพื่อเข้าถึงUserMapDataFrameวัตถุจากที่เกี่ยวข้องUserการโทรเริ่มต้นจะเป็นUser.usermapdataframe_set.all()ซึ่งมันค่อนข้างยากที่จะอ่าน

การใช้ตัวrelated_nameช่วยให้คุณสามารถระบุชื่อที่ง่ายกว่าหรือชัดเจนกว่าเพื่อให้ได้ความสัมพันธ์แบบย้อนกลับ ในกรณีนี้ถ้าคุณระบุโทรก็จะเป็นuser = models.ForeignKey(User, related_name='map_data')User.map_data.all()


3

พารามิเตอร์ชื่อที่เกี่ยวข้องเป็นตัวเลือกจริง ๆ หากเราไม่ได้ตั้งไว้ Django จะสร้างอีกด้านหนึ่งของความสัมพันธ์สำหรับเราโดยอัตโนมัติ ในกรณีของโมเดลแผนที่ Django จะสร้างแอmap_setททริบิวต์ขึ้นมาเพื่อให้สามารถเข้าถึงได้m.map_setในตัวอย่างของคุณ (เป็นอินสแตนซ์ของคลาสของคุณ) สูตร Django _setใช้เป็นชื่อของรูปแบบตามด้วยสตริง พารามิเตอร์ชื่อที่เกี่ยวข้องนั้นจะแทนที่ค่าเริ่มต้นของ Django ได้ง่าย ๆ แทนที่จะให้พฤติกรรมใหม่


0

prefetch_relatedใช้สำหรับดึงข้อมูลล่วงหน้าสำหรับข้อมูลความสัมพันธ์หลายต่อหลายและหลายต่อหนึ่ง select_relatedคือการเลือกข้อมูลจากความสัมพันธ์ของค่าเดียว ทั้งสองอย่างนี้ใช้เพื่อดึงข้อมูลจากความสัมพันธ์จากแบบจำลอง ตัวอย่างเช่นคุณสร้างโมเดลและโมเดลที่มีความสัมพันธ์กับโมเดลอื่น เมื่อคำขอมาคุณจะค้นหาข้อมูลความสัมพันธ์ของพวกเขาและ Django มีกลไกที่ดีมากในการเข้าถึงข้อมูลจากความสัมพันธ์ของพวกเขาเช่นbook.author.nameแต่เมื่อคุณย้ำรายการรุ่นสำหรับดึงข้อมูลความสัมพันธ์ของพวกเขา Django สร้างแต่ละคำขอสำหรับข้อมูลความสัมพันธ์แต่ละรายการ เพื่อเอาชนะสิ่งนี้เรามี prefetchd_relatedและselected_related

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