As noted in other questions, Django experts like Two Scoops recommend explicit OneToOneFields rather than multi-table inheritance to avoid performance penalties of implicit joins. I have tried to follow such an approach, and my design is actually object composition, but have a few questions. All three of these are concrete tables.
class Widget:
... many shared fields ...
class FunWidget:
parent = models.OneToOneField(Widget, related_name='child', primary_key=True)
... fun-specific fields ...
class WorkWidget:
parent = models.OneToOneField(Widget, related_name='child', primary_key=True)
... work-specific fields ...
My questions are:
Related name: Given a
Widget
, it'd be nice to refer to its related subtype with the same name, e.g.,Widget.child
. However, I get aReverse query name for ... clashes with reverse query name for ...
error. Therefore, it seems I must provide differentrelated_name
s, so that a givenWidget
would have either a.funwidget
or a.workwidget
. To generalize I could provide a methodWidget.child()
which checks each of the possiblerelated_name
s, but that won't help me in queries.Filtering by Subtype: Given a
QuerySet
ofWidget
, I need to filter to all which are of a given "subtype". I realize you'd normally just query the child model, but this is for a custom query set forWidget
where I need to perform different filtering based on the type of "subclass". In other words, I want something like thisWidget.objects.filter(isinstance(child, WorkWidget))
which I realize isn't possible. Currently I am "duck typing" by checking for some different property of Widget (my dilemma from question 1 provides such a feature). Cleaner would be to store an explicit.type
field, if I must.
I've failed to find a simple example with this kind of explicit one-to-one mapping.