Django'da `related_name` ne için kullanılır?


390

related_nameArg ve on ManyToManyFieldve ForeignKeyalanlar için yararlı olan nedir ? Örneğin, aşağıdaki kod verildiğinde, etkisi related_name='maps'nedir?

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

12
@DanielRoseman Geriye dönük bir ilişki gerekli olmadığında performans veya iyi uygulama için related_name = '+' kullanmak bir şekilde iyi midir?
lajarre

10
@ Lajarre'nin sorusunun cevabını bilmek isterdim.
cheesewheel

1
@lajarre - Bunun performansı hiç değiştirmeyeceğini düşünüyorum. FeinCMS içerik türleriyle bir kez kullanmak zorunda kaldım. Kişisel olarak her zaman belirtmenin iyi bir uygulama olduğunu düşünüyorum, related_namebu yüzden kullanmayacağınızı biliyorsanız, iyi bir şey olduğunu düşünüyorum. Tabii ki bu kişisel bir görüş.
François Constant

@ 3cheesewheel şu anda dokümanlardaydı: docs.djangoproject.com/en/2.0/ref/models/fields/… + ters ilişki oluşturmamak anlamına geliyor
P. Myer Nore

Yanıtlar:


530

related_nameNitelik ters ilişki adını belirtir Usermodelinize modeli arka.

Bir belirtmezseniz related_name, Django otomatik soneki ile modelin adını kullanarak birini oluşturur _setörneğin User.map_set.all().

Eğer varsa yok , mesela belirtmek related_name=mapsüzerinde Usermodelin, User.map_setçalışma hala alırım ama User.maps.sözdizimi açıkçası biraz daha temiz ve daha az aksak; örneğin, bir kullanıcı nesneniz current_uservarsa current_user.maps.all(), Mapmodelinizin bir ilişkisi olan tüm örneklerini almak için kullanabilirsiniz current_user.

Django belgeleri daha fazla ayrıntı vardır.


1
Tamam, bunun eski bir yazı olduğunu biliyorum. Ama sadece bunu anlamaya çalışıyorum - ilgili adın sonundaki + hile nedir? Örneğin, related_name='maps+'yukarıdaki örnekte yapmışsam ne olur ?
Sidd

10
+ 'yı eklerseniz, django eşlemeyi devre dışı bırakır
josephmisiti

5
OneToOneField için varsayılan related_name küçük harf sınıfı adı olacaktır. Örneğin verilen örnekte üyeler OneToOnefield olacaksa "User.map" çalışacaktır.
ancho

belirtirseniz related_name, _sethala çalışıyor mu django1.11 >??
Esir Kings

9
Django 2.1.3 kullanıyorum ve bunların özel olduğunu not edebilirim. Bir kez related_namebelirtildiğinde, _setartık çalışmaz.
stockersky

83

Modelde aynı tabloya işaret eden 2 FK olması durumunda mevcut yanıtla ilgili isme eklemek şarttır. Örneğin, malzeme listesi durumunda

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

Bu nedenle, bu verilere erişmeniz gerektiğinde yalnızca ilgili adı kullanabilirsiniz

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

Aksi halde çalışmıyor (en azından 2 FK'nin aynı tabloya gelmesi durumunda ilgili adın kullanımını atlayamadım.)


2
Bunlardan en az biri için ilgili bir isim seçmelisiniz. Diğeri zorunlu olarak gerektirmiyor.
Csaba Toth

32
related_nameçoğul olmalıdır. Çünkü ForeignKey ilişkileri birden fazla nesne döndürür.
Mesut Tasci

10

related_nameEğer daha karmaşık ilgili sınıf isimleri varsa argüman da yararlıdır. Örneğin, yabancı bir anahtar ilişkiniz varsa:

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

UserMapDataFrameİlgili nesnelerden nesnelere erişmek Useriçin varsayılan çağrı User.usermapdataframe_set.all(), okunması oldukça zordur.

Kullanma related_nameseçeneği, ters ilişkiyi elde etmek için daha basit veya daha okunaklı bir ad belirlemenizi sağlar. Bu durumda, belirtirseniz user = models.ForeignKey(User, related_name='map_data'), çağrı olur User.map_data.all().


3

İlgili ad parametresi aslında bir seçenektir. Ayarlamazsak, Django otomatik olarak ilişkinin diğer tarafını bizim için yaratır. Harita modeli söz konusu olduğunda, Django örneğinizde map_seterişime izin veren bir özellik yaratırdı m.map_set(m sizin sınıf örneğinizdir). Django'nun kullandığı formül, modelin adını ve ardından dizeyi gösterir _set. İlgili ad parametresi, yeni davranış sağlamak yerine Django'nun varsayılan değerini geçersiz kılar.


0

prefetch_relatedÇoktan çoğa ve çoktan bire ilişki verileri için önceden getirme verileri için kullanın. select_relatedtek bir değer ilişkisinden veri seçmektir. Bunların her ikisi de bir modelden ilişkilerinden veri almak için kullanılır. Örneğin, diğer modellerle ilişkisi olan bir model ve model oluşturursunuz. Bir istek geldiğinde, ilişki verilerini de sorgulayacaksınız ve Django'nun ilişkilerinden verilere erişmek için çok iyi mekanizmaları var, book.author.nameancak ilişki verilerini almak için bir model listesi yinelediğinizde Django, her ilişki verisi için her isteği oluşturur. Bunun üstesinden gelmek için zamanımız var prefetchd_relatedveselected_related

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.