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.


  • You are right, the related names must differ.
  • Simply check for the existence of the given subtype:

    Widget.objects.select_related('workwidget').filter(workwidget__isnull=False)

  • 链接地址: http://www.djcxy.com/p/60212.html

    上一篇: Django ORM将孩子的数量分组

    下一篇: Django的对象组成与OneToOneField