django - What are the pros and cons of using GenericForeignKey vs multitable inheritance vs OneToOneField? -
context
i in process of modeling data using django models. main model article
. holds actual content.
then each article
must attached group of articles. group may blog
, category
portfolio
or story
. every article
must attached one, , 1 of those. is, either blog, category or story. models have different fields , features.
i thought of 3 ways reach goal (and bonus 1 looks wrong).
option #1: generic foreign key
as in django.contrib.contenttypes.fields.genericforeignkey
. this:
class category(model): # fields class blog(model): # some fields class article(model): group_type = foreignkey(contenttype) group_id = positiveintegerfield() group = genericforeignkey('group_type', 'group_id') # fields
on database side, means no relation exists between models, enforced django.
option #2: multitable inheritance
make article groups inherit articlegroup
model. this:
class articlegroup(model): group_type = foreignkey(contenttype) class category(articlegroup): # fields class blog(articlegroup): # fields class article(model): group = foreignkey(articlegroup) # fields
on database side, creates additional table articlegroup
, category
, blog
have implicit foreign key table primary key.
sidenote: i know there a package automates bookkeeping of such constructions.
option #3: manual onetoonefields
on database side, equivalent option #2. in code, relations made explicit:
class articlegroup(model): group_type = foreignkey(contenttype) class category(model): id = onetoonefield(articlegroup, primary_key=true) # fields class blog(model): id = onetoonefield(articlegroup, primary_key=true) # fields class article(model): group = foreignkey(articlegroup) # fields
i don't see point of be, apart making explicit django's inheritance magic implicitly does.
bonus: multicolumn
it seems pretty dirty add bonus, possible define nullable foreignkey each of category
, blog
, ... directly on article
model.
so...
...i cannot decide between those. pros , cons of each approach? there best practices? did miss better approach?
if matters, i'm using django 1.8.
it seems noone had advice share on one. chose multicolumn option, despite having said looked ugly. came down 3 things:
- database-based enforceability.
- the way django orm works different constructs.
- my own needs (namely, collection queries on group item list, , individual queries on items group).
option #1
- cannot enforced @ database level.
- could efficient on queries because way constructed not fall usual generic foreign key pitfalls. happen when items generic, not collections.
- however, due how orm handles gfk, impossible use custom manager, need because articles translated using django-hvad.
option #2
- can enforced @ database level.
- could efficient, runs orm limitations, not built around use. unless use
extra()
or custom queries alot, @ point there no reason use orm anymore.
option #3
- would bit better #2, making things explicit allows easier query optimisation while using orm.
multicolumn
- turns out not being bad. can enforced @ database level (fk constraints plus manual check ensure 1 of columns non-null).
- easy , efficient. single intuitive query job:
select_related('category', 'blog', ...)
. - though have issue of being harder extend (any new type require altering
article
's table well) , limiting possible number of types, i'm unlikely run those.
hope helps same dilemma, , still interested in hearing other opinions.
Comments
Post a Comment