Django object composition with OneToOneField
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, eg, Widget.child . However, I get a Reverse query name for ... clashes with reverse query name for ... error. Therefore, it seems I must provide different related_name s, so that a given Widget would have either a .funwidget or a .workwidget . To generalize I could provide a method Widget.child() which checks each of the possible related_name s, but that won't help me in queries.
Filtering by Subtype: Given a QuerySet of Widget , 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 for Widget where I need to perform different filtering based on the type of "subclass". In other words, I want something like this Widget.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.
Simply check for the existence of the given subtype:
Widget.objects.select_related('workwidget').filter(workwidget__isnull=False)
上一篇: Django ORM将孩子的数量分组
