Untuk apa `related_name` digunakan di Django?

391

Apa related_nameargumen yang berguna untuk bidang ManyToManyFielddan ForeignKeybidang? Misalnya, mengingat kode berikut, apa efeknya related_name='maps'?

class Map(db.Model):
    members = models.ManyToManyField(User, related_name='maps',
                                     verbose_name=_('members'))
zjm1126
sumber
12
@DanielRoseman Apakah itu entah bagaimana baik untuk kinerja atau praktik yang baik untuk menggunakan related_name = '+' ketika hubungan mundur tidak diperlukan?
lajarre
10
Saya ingin tahu untuk mengetahui jawaban atas pertanyaan @ lajarre.
3cheesewheel
1
@ajarre - Saya berasumsi bahwa tidak akan mengubah kinerja sama sekali. Saya harus menggunakannya sekali dengan tipe konten FeinCMS. Saya pribadi berpikir itu praktik yang baik untuk selalu menentukan related_namejadi jika Anda tahu Anda tidak akan menggunakannya, saya kira itu hal yang baik. Itu pendapat pribadi tentunya.
François Constant
@ 3cheesewheel ada di dalam dokumen sekarang: docs.djangoproject.com/en/2.0/ref/models/fields/… + berarti tidak membuat hubungan terbalik
P. Myer Nore

Jawaban:

531

The related_nameatribut menentukan nama hubungan terbalik dari Usermodel yang kembali ke model Anda.

Jika Anda tidak menentukan related_name, Django secara otomatis membuat satu menggunakan nama model Anda dengan suffix _set, misalnya User.map_set.all().

Jika Anda tidak menentukan, misalnya related_name=mapspada Usermodel User.map_setakan tetap bekerja, tetapi User.maps.sintaks jelas sedikit lebih bersih dan kurang kikuk; jadi misalnya, jika Anda memiliki objek pengguna current_user, Anda bisa menggunakan current_user.maps.all()untuk mendapatkan semua instance dari Mapmodel Anda yang memiliki hubungan dengan current_user.

The dokumentasi Django memiliki rincian lebih lanjut.

Wogan
sumber
1
Oke, saya tahu ini posting lama. Tapi saya hanya mencoba mencari tahu ini - apa trik + di akhir nama terkait? Misalnya, apa yang terjadi jika saya lakukan related_name='maps+'pada contoh di atas?
Sidd
10
jika Anda menambahkan +, Django menonaktifkan pemetaan
josephmisiti
5
untuk OneToOneField default related_name akan menjadi nama kelas kasus kecil. Misalnya dalam contoh yang diberikan jika anggota akan OneToOnefield maka "User.map" akan berfungsi.
ancho
jika Anda tentukan related_name, apakah _setmasih berfungsi django1.11 >??
Esir Kings
9
Saya menggunakan Django 2.1.3 dan saya perhatikan itu eksklusif. Setelah related_nameditentukan, _settidak berfungsi lagi.
stockersky
84

Untuk menambah nama terkait jawaban yang ada adalah suatu keharusan jika ada 2 FK dalam model yang menunjuk ke tabel yang sama. Misalnya dalam hal Bill of material

@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)

Jadi ketika Anda harus mengakses data ini, Anda hanya dapat menggunakan nama terkait

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

Itu tidak berfungsi sebaliknya (setidaknya saya tidak bisa melewati penggunaan nama terkait dalam kasus 2 FK ke tabel yang sama.)

Ilya Bibik
sumber
2
Anda harus memilih nama terkait setidaknya untuk salah satu dari mereka. Yang lain tidak membutuhkan secara khusus.
Csaba Toth
32
related_nameharus jamak. Karena hubungan ForeignKey mengembalikan beberapa objek.
Mesut Tasci
11

The related_nameArgumen ini juga berguna jika Anda memiliki nama kelas terkait yang lebih kompleks. Misalnya, jika Anda memiliki hubungan kunci asing:

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

Untuk mengakses UserMapDataFrameobjek dari yang terkait User, panggilan defaultnya adalah User.usermapdataframe_set.all(), yang cukup sulit dibaca.

Menggunakan related_namememungkinkan Anda untuk menentukan nama yang lebih sederhana atau lebih mudah dibaca untuk mendapatkan hubungan terbalik. Dalam hal ini, jika Anda menentukan user = models.ForeignKey(User, related_name='map_data'), panggilan itu akan menjadi User.map_data.all().

Daniel Holmes
sumber
3

Parameter nama terkait sebenarnya merupakan opsi. Jika kita tidak mengaturnya, Django secara otomatis membuat sisi lain dari relasi untuk kita. Dalam kasus model Peta, Django akan membuat map_setatribut, yang memungkinkan akses melalui m.map_setdalam contoh Anda (m menjadi instance kelas Anda). Rumus yang digunakan Django adalah nama model yang diikuti oleh string _set. Parameter nama terkait dengan demikian hanya menimpa standar Django daripada memberikan perilaku baru.

Abrar
sumber
0

prefetch_relatedgunakan untuk data prefetch untuk Many to many dan many to one relationship data. select_relatedadalah memilih data dari hubungan nilai tunggal. Keduanya digunakan untuk mengambil data dari hubungan mereka dari suatu model. Misalnya, Anda membangun model dan model yang memiliki hubungan dengan model lain. Ketika permintaan datang, Anda juga akan meminta data hubungan mereka dan Django memiliki mekanisme yang sangat baik Untuk mengakses data dari hubungan mereka seperti book.author.nametetapi ketika Anda mengulang daftar model untuk mengambil data hubungan mereka, Django membuat setiap permintaan untuk setiap data hubungan tunggal. Untuk mengatasi ini kita memang punya prefetchd_relateddanselected_related

Jamil Noyda
sumber