Sono in procinto di modellare i miei dati utilizzando i modelli Django. Il modello principale è un Article
. Tiene il contenuto reale.
Quindi ogni Article
deve essere collegato a un gruppo di articoli. Quel gruppo può essere uno Blog
, uno Category
uno Portfolio
o uno Story
. Ogni Article
deve essere collegato a uno, ed esattamente uno di quelli. Cioè, un blog, una categoria o una storia. Questi modelli hanno campi e caratteristiche molto diversi.
Ho pensato a tre modi per raggiungere questo obiettivo (e uno bonus che sembra davvero sbagliato).
Opzione 1: un generico stranieri chiave
Come in django.contrib.contenttypes.fields.GenericForeignKey
. Si sarebbe simile a questa:
class Category(Model):
# some fields
class Blog(Model):
# some fields
class Article(Model):
group_type = ForeignKey(ContentType)
group_id = PositiveIntegerField()
group = GenericForeignKey('group_type', 'group_id')
# some fields
Sul lato del database, che significa nessuna relazione esiste in realtà tra i modelli, la loro applicazione da Django.
Opzione # 2: l'eredità Multitable
gruppi di articoli Eseguire tutti ereditano da un modello ArticleGroup
. Questo sarebbe simile a questa:
class ArticleGroup(Model):
group_type = ForeignKey(ContentType)
class Category(ArticleGroup):
# some fields
class Blog(ArticleGroup):
# some fields
class Article(Model):
group = ForeignKey(ArticleGroup)
# some fields
Sul lato database, questo crea una tabella aggiuntiva per ArticleGroup
, quindi Category
e Blog
avere una chiave esterna implicito a quel tavolo come loro chiave primaria.
Sidenote: So che c'è a package che automatizza la contabilità di tali costruzioni.
Opzione # 3: OneToOneFields manuali
Dal punto di vista del database, è equivalente a opzione # 2. Ma nel codice, tutte le relazioni sono rese esplicite:
class ArticleGroup(Model):
group_type = ForeignKey(ContentType)
class Category(Model):
id = OneToOneField(ArticleGroup, primary_key=True)
# some fields
class Blog(Model):
id = OneToOneField(ArticleGroup, primary_key=True)
# some fields
class Article(Model):
group = ForeignKey(ArticleGroup)
# some fields
io non vedo quale sarebbe il punto di che, oltre a fare esplicito ciò che la magia eredità di Django fa implicitamente.
Bonus: più colonne
Sembra abbastanza sporca così ho aggiungerlo come bonus, ma sarebbe anche possibile definire una ForeignKey nullable a ciascuno dei Category
, Blog
, ... direttamente sul Modello Article
.
Quindi ...
... non posso davvero decidere tra quelli. Quali sono i pro e i contro di ciascun approccio? Ci sono delle buone pratiche? Ho perso un approccio migliore?
Se è importante, sto utilizzando Django 1.8.
Sono d'accordo: l'opzione a più colonne è la migliore finché si prevede di avere solo un numero limitato di classi a cui potrebbe essere collegato.Per questo caso d'uso, GFK è male IMO, perché crea un buco nell'integrità del database e rende le query al di fuori di Django particolarmente difficili. – spookylukey