ParentModel and ChildManager for Model Inheritance

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
from django.db import models
from django.db.models.query import QuerySet


class ChildQuerySet(QuerySet):
    def iterator(self):
        for obj in super(ChildQuerySet, self).iterator():
            yield obj.get_child_object()


class ChildManager(models.Manager):
    def get_query_set(self):
        return ChildQuerySet(self.model)


class ParentModel(models.Model):
    _child_name = models.CharField(max_length=100, editable=False)

    class Meta:
        abstract = True

    def save(self, *args, **kwargs):
        self._child_name = self.get_child_name()
        super(ParentModel, self).save(*args, **kwargs)

    def get_child_name(self):
        if type(self) is self.get_parent_model():
            return self._child_name
        return self.get_parent_link().related_query_name()

    def get_child_object(self):
        return getattr(self, self.get_child_name())

    def get_parent_link(self):
        return self._meta.parents[self.get_parent_model()]

    def get_parent_model(self):
        raise NotImplementedError

    def get_parent_object(self):
        return getattr(self, self.get_parent_link().name)

More like this

  1. Multiple querysets by t_rybik 4 years, 1 month ago
  2. Custom managers with chainable filters by itavor 6 years, 2 months ago
  3. Finding related objects for instances in a queryset by akaihola 3 years, 1 month ago
  4. Bitwise operator queryset filter by hgeerts@osso.nl 3 years, 11 months ago
  5. Polymorphic inheritance ala SQLAlchemy by gsakkis 3 years, 6 months ago

Comments

donspaulding (on September 8, 2008):

Nice.

1031 and 1034 solved the problem, but this was the usage I was looking to get from the solution. Thanks!

#

neithere (on November 2, 2008):

Thanks, excellent snippet!

#

carljm (on February 5, 2009):

Slick.

#

BUZZY (on December 3, 2012):

That's exactly what I was looking for, thanks!

#

(Forgotten your password?)