Definiuję teraz moje modele Django i zdałem sobie sprawę, że nie ma OneToManyField
w modelu pól typów. Jestem pewien, że można to zrobić, więc nie wiem, czego mi brakuje. Zasadniczo mam coś takiego:
class Dude(models.Model):
numbers = models.OneToManyField('PhoneNumber')
class PhoneNumber(models.Model):
number = models.CharField()
W tym przypadku, każdy Dude
może mieć wiele PhoneNumber
s, ale związek powinien być jednokierunkowy, że nie muszę wiedzieć, z PhoneNumber
którego Dude
jest właścicielem, per se, jak mogę mieć wiele różnych obiektów, które własne PhoneNumber
przypadki, takie jak Business
na przykład:
class Business(models.Model):
numbers = models.OneToManyField('PhoneNumber')
Co zastąpiłbym OneToManyField
(czego nie ma) w modelu, aby przedstawić ten rodzaj relacji? Pochodzę z Hibernate / JPA, gdzie zadeklarowanie relacji jeden do wielu było tak proste, jak:
@OneToMany
private List<PhoneNumber> phoneNumbers;
Jak mogę to wyrazić w Django?
źródło
dude = models.ForeignKey(Dude, related_name='numbers')
a następnie możesz użyćsome_dude_object.numbers.all()
do uzyskania wszystkich powiązanych numerów (jeśli nie określisz „related_name”, domyślnie zostanie to „number_set”).W Django relacja jeden do wielu nazywa się ForeignKey. Działa jednak tylko w jednym kierunku, więc zamiast mieć
number
atrybut klasyDude
, będziesz potrzebowaćWiele modeli może mieć
ForeignKey
jeden inny model, więc byłoby ważne, aby mieć drugi atrybutPhoneNumber
takiego typuMożesz uzyskać dostęp do
PhoneNumber
s dlaDude
obiektu zad
pomocąd.phonenumber_set.objects.all()
, a następnie zrobić to samo dlaBusiness
obiektu.źródło
ForeignKey
oznacza to „jeden do jednego”. Korzystając z powyższego przykładu, powinienem miećDude
wiele,PhoneNumbers
prawda?ForeignKey
jest tylko jeden do jednego, jeśli określiszForeignKey(Dude, unique=True)
, więc z powyższym kodem otrzymaszDude
z wielomaPhoneNumber
s.PhoneNumber
. Teraz zaczyna mieć sens.ForeignKey
jest w zasadzie wiele-do-jednego, więc musisz to zrobić wstecz, aby uzyskać jeden do wielu :)phonenumber_set
? Nie widzę tego nigdzie zdefiniowanego. Czy jest to nazwa modelu, pisana małymi literami, z dopiskiem „_set”?Żeby było jasne - w Django nie ma OneToMany, tylko ManyToOne - czyli Foreignkey opisanego powyżej. Możesz opisać relację OneToMany za pomocą klucza obcego, ale jest to bardzo niewyrażalne.
Dobry artykuł na ten temat: https://amir.rachum.com/blog/2013/06/15/a-case-for-a-onetomany-relationship-in-django/
źródło
Możesz użyć klucza obcego po wielu stronach
OneToMany
relacji (tj.ManyToOne
Relacji) lub użyćManyToMany
(po dowolnej stronie) z ograniczeniem unikalności.źródło
django
jest wystarczająco inteligentny. Właściwie nie musimy definiowaćoneToMany
pola. Zostanie automatycznie wygenerowany przezdjango
:-). Musimy tylko zdefiniowaćforeignKey
w powiązanej tabeli. Innymi słowy, wystarczy zdefiniowaćManyToOne
relację za pomocąforeignKey
.jeśli chcemy uzyskać listę kół danego samochodu. użyjemy
python's
automatycznie wygenerowanego obiektuwheel_set
. Do samochodu,c
którego będziesz używaćc.wheel_set.all()
źródło
Chociaż odpowiedź Rolling Stone jest dobra, prosta i funkcjonalna, myślę, że są dwie rzeczy, których nie rozwiązuje.
Przedstaw strukturę typów zawartości , która udostępnia niektóre obiekty, które pozwalają nam utworzyć „ogólny klucz obcy” w modelu PhoneNumber. Następnie możemy zdefiniować odwrotną relację w przypadku gościa i biznesu
Zobacz dokumentację, aby uzyskać szczegółowe informacje, i być może zapoznaj się z tym artykułem, aby uzyskać krótki samouczek.
Tutaj jest również artykuł, w którym argumentuje się przeciwko używaniu generycznych FK.
źródło
Jeśli model „wiele” nie uzasadnia tworzenia modelu jako takiego (nie w tym przypadku, ale może przynieść korzyści innym osobom), inną alternatywą byłoby poleganie na określonych typach danych PostgreSQL za pośrednictwem pakietu Django Contrib
Postgres może radzić sobie z typami danych Array lub JSON i może to być przyjemne obejście do obsługi typu jeden do wielu, gdy wiele-ies można powiązać tylko z jedną jednostką jednego .
Postgres umożliwia dostęp do pojedynczych elementów tablicy, co oznacza, że zapytania mogą być naprawdę szybkie i pozwalają uniknąć narzutów na poziomie aplikacji. Oczywiście Django implementuje fajne API, aby wykorzystać tę funkcję.
Oczywiście ma tę wadę, że nie można go przenosić na inne zaplecze bazy danych, ale myślę, że nadal warto o tym wspomnieć.
Mam nadzieję, że pomoże to niektórym osobom szukającym pomysłów.
źródło
Przede wszystkim zwiedzamy:
01) relacja jeden do wielu:
Uwaga: Django nie zapewnia żadnej relacji OneToMany. Więc nie możemy użyć metody górnej w Django. Ale musimy przejść do modelu relacyjnego. Więc co możemy zrobić? W tej sytuacji musimy przekształcić model relacyjny w odwrotny model relacyjny.
Tutaj:
model relacyjny = OneToMany
Zatem odwrotny model relacyjny = ManyToOne
Uwaga: Django obsługuje relacje ManyToOne, aw Django ManyToOne jest reprezentowane przez ForeignKey.
02) relacja wiele do jednego:
NB: MYŚL PO PROSTU !!
źródło