2015-11-04 13 views
5

Więc mam pytanie, które myślałem o stworzeniu pojedynczej tabeli, która ma klucz obcy dla kilku innych tabel, i używając innego pola "typ", aby powiedzieć, do której tabeli klucz powinien należeć .Django modeluje jeden klucz obcy dla wielu tabel

class Status(Models.model): 
    request = models.ForeignKey("Request1", "Request2", "Request3") 
    request_type = models.IntegerField() 
    ...Some status related data 

class Request1(Models.model): 
    ...Some data 

class Request2(Models.model): 
    ...Some other data 

Class Request3(Models.model): 
    ...different data 

Moje pytanie brzmi, czy można zdefiniować taki klucz obcy? Innym rozwiązaniem myślałem było określenie mojego modelu jak ten

class Status(Models.model): 
    request1 = models.ForeignKey("Request1") 
    request2 = models.ForeignKey("Request2") 
    request3 = models.ForeignKey("Request3") 
    ...Some status related data 

class Request1(Models.model): 
    ...Some data 

class Request2(Models.model): 
    ...Some other data 

Class Request3(Models.model): 
    ...different data 

Ale jeśli to zrobię to w ten sposób możliwe jest zdefiniowanie ograniczenie poprzez Django, który mówi tylko 1 klucz obcy może mieć dane, a drugi dwie muszą być zerowe? lub będę musiał ściśle ustawić to ograniczenie na stronie db. (Używam postgres) Chciałbym móc powiedzieć django, aby to zrobić, gdy tworzy db, więc nie muszę pamiętać za każdym razem, gdy ktoś odtwarza bazę danych.

Wszelkie uwagi i rady są mile widziane. Nie jestem żonaty z żadnym z tych pomysłów, więc jeśli istnieje inny sprytny sposób osiągnięcia tego samego efektu, to jestem gotów to usłyszeć. Dziękuję za Twój czas.

Edycja: używam Django 1.7.10

+0

Chcesz po prostu jednym z trzech jest FK? –

+0

Przepraszam, tak, każdy status powinien zawierać tylko jedno żądanie. – mingle

Odpowiedz

12

Należy użyć ramy contentypes w Django.

Jest przykładem dla ogólnego stosunku tutaj: https://docs.djangoproject.com/en/1.8/ref/contrib/contenttypes/#generic-relations Dla wymogu mogłoby to wyglądać mniej więcej tak:

from django.db import models 
from django.contrib.contenttypes.fields import GenericForeignKey 
from django.contrib.contenttypes.models import ContentType 

class Status(models.Model): 
    request_type = models.ForeignKey(ContentType) 
    request_id = models.PositiveIntegerField() 
    request = GenericForeignKey('request_type', 'request_id') 

Następnie można zrobić coś jak następuje:

status1 = Status(request=Request1("foo")) 
status1.save() 
status2 = Status(request=Request2("bar")) 
status2.save() 

status1.request // <Request1 "foo"> 
status1.request // <Request2 "bar"> 
+0

Wow to wygląda dokładnie tak, jak tego szukałem. Bardzo dziękuję – mingle

+0

Haha, tak. Dobra intuicja ;-) – Sebastian

+0

Dobra, mam pytanie: Jak uzyskać dostęp do obiektu statusu z foo lub obiektu? –