May 13, 2012

Building a higher-level query API: the right way to use django's ORM

Approach 2: Manager methods
class TodoManager(models.Manager):
    def incomplete(self):
        return self.filter(is_done=False)

    def high_priority(self):
        return self.filter(priority=1)

class Todo(models.Model):
    content = models.CharField(max_length=100)
    # other fields go here..

    objects = TodoManager()

Todo.objects.incomplete()
Todo.objects.high_priority()

# and (from comments)

incomplete_and_high_priority = Todo.objects.incomplete() & Todo.objects.hight_priority()
Approach 3a: copy Django, proxy everything
class TodoQuerySet(models.query.QuerySet):
    def incomplete(self):
        return self.filter(is_done=False)

    def high_priority(self):
        return self.filter(priority=1)

class TodoManager(models.Manager):
    def get_query_set(self):
        return TodoQuerySet(self.model, using=self._db)

    def incomplete(self):
        return self.get_query_set().incomplete()

    def high_priority(self):
        return self.get_query_set().high_priority()

Todo.objects.incomplete().high_priority()
Approach 3b: django-model-utils
from model_utils.managers import PassThroughManager

class TodoQuerySet(models.query.QuerySet):
    def incomplete(self):
        return self.filter(is_done=False)

    def high_priority(self):
        return self.filter(priority=1)

class Todo(models.Model):
    content = models.CharField(max_length=100)
    # other fields go here..

    objects = PassThroughManager.for_queryset_class(TodoQuerySet)()

Original: http://dabapps.com/blog/higher-level-query-api-django-orm/

No comments: