2010-04-15 11 views
192

Jaki jest argument related_name przydatny dla pól i ForeignKey? Na przykład, biorąc pod uwagę następujący kod, jaki jest efekt related_name='maps'?Co to jest nazwa powiązana używany w Django?

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

@DanielRoseman Czy korzystanie z funkcji related_name = '+' jest w jakiś sposób dobre dla wydajności lub dobrej praktyki, gdy relacja wstecz nie jest konieczna? – lajarre

+7

Chciałbym poznać odpowiedź na pytanie @ lajarre. – 3cheesewheel

+1

@lajarre - Zakładam, że wcale nie zmieni to wydajności. Musiałem użyć go raz z typami treści FeinCMS. Osobiście uważam, że dobrą praktyką jest zawsze określać "powiązaną nazwę", więc jeśli wiesz, że nie będziesz jej używał, to chyba dobrze. To oczywiście osobista opinia. –

Odpowiedz

275

Atrybut related_name określa nazwę odwrotnej relacji z User modelu z powrotem do swojego modelu.

Jeśli nie określisz related_name, Django automatycznie tworzy jeden używając nazwy modelu z przyrostkiem _set, na przykład User.map_set.all().

Jeśli podłączysz do, related_name=maps na modelu User, User.map_set nadal będzie działał, ale składnia User.maps. jest oczywiście nieco czystsza i mniej przylegająca; więc na przykład, jeśli masz obiekt użytkownika current_user, możesz użyć current_user.maps.all(), aby uzyskać wszystkie wystąpienia modelu Map, które mają związek z current_user.

The Django documentation ma więcej szczegółów.

+1

OK, wiem, że to stary post. Ale próbuję to rozgryźć - jaka jest + sztuczka na końcu powiązanego imienia? Na przykład, co się stanie, jeśli zrobiłem 'related_name = 'maps +'' w powyższym przykładzie? – Sidd

+4

jeśli dodasz +, django wyłączy mapowanie – josephmisiti

+2

dla OneToOneField default nazwa_końcowa będzie małą nazwą klasy. Na przykład w podanym przykładzie, jeśli członkowie będą OneToOnefield, "User.map" będzie działać. – ancho

32

Dodawanie do istniejącej nazwy związanej z odpowiedzią jest koniecznością na wypadek, gdyby w modelu znajdowały się 2 wartości FK wskazujące tę samą tabelę. Na przykład w przypadku Billa materiału

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

Więc kiedy będziesz mieć dostęp do tych danych można tylko użyć związanej nazwę

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

To nie działa inaczej (przynajmniej ja nie był w stanie aby pominąć użycie powiązanej nazwy w przypadku 2 FK do tego samego stołu.)

+1

Musisz wybrać related_name przynajmniej dla jednego z nich. Drugi nie wymaga od ciebie. –

+3

'related_name' powinno być w liczbie mnogiej. Ponieważ relacje ForeignKey zwracają wiele obiektów. –