Login

QuerySetManager - easily add new QuerySet methods using a Model inner class

Author:
simon
Posted:
May 1, 2008
Language:
Python
Version:
.96
Tags:
orm manager queryset
Score:
7 (after 9 ratings)

An easy way to add custom methods to the QuerySet used by a Django model. See simonwillison.net/2008/May/1/orm/ for an in-depth explanation.

 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
from django.db import models

class QuerySetManager(models.Manager):
    def get_query_set(self):
        return self.model.QuerySet(self.model)

# Using it in a model:

from django.db.models.query import QuerySet
import datetime

class Entry(models.Model):
   ...
   objects = QuerySetManager()
   ...
   class QuerySet(QuerySet):
        def on_date(self, date):
            next = date + datetime.timedelta(days = 1)
            return self.filter(
                posted__gt = date,
                posted__lt = next
            )

# Now you can get entries on a specific day like so:
#   Entry.objects.all().on_date(datetime.date.today())

More like this

  1. Custom Model Manager Chaining by hunterford 6 years, 1 month ago
  2. Add Extra Headers to Test Client Requests by luftyluft 8 years, 1 month ago
  3. Easier chainability with custom QuerySets by bendavis78 4 years, 5 months ago
  4. Fire Eagle example: views.py from wikinear.com by simon 8 years, 5 months ago
  5. Easier custom Model Manager Chaining by gsakkis 6 years, 1 month ago

Comments

dnordberg (on May 6, 2008):
<p>This works for Entry.objects.filter().on_date(date) but not Entry.objects.on_date(date) as some may wish, for this add the following snippet to QuerySetManager.</p> <p>`</p> <pre>def __getattr__(self, attr, *args): try: return getattr(self.__class__, attr, *args) except AttributeError: return getattr(self.get_query_set(), attr, *args) </pre> <p>`</p>

#

exogen (on May 8, 2008):
<p>In response to the above comment, I believe it can simple be written as:</p> <pre>def __getattr__(self, name): return getattr(self.get_query_set(), name) </pre> <p>...since the default attribute lookup will check self.class and superclasses.</p>

#

zodiac2832 (on July 28, 2011):
<p>I had to modify my manager to the following so I would not receive Pickle Errors.</p> <pre># pickling causes recursion errors _deny_methods = ['__getstate__', '__setstate__', '_db'] def __init__(self, queryset_cls=None): self._queryset_cls = queryset_cls super(PadManager, self).__init__() def __getattr__(self, name): if name in self._deny_methods: raise AttributeError(name) return getattr(self.get_query_set(), name) def get_query_set(self): return PadQuerySet(self.model) </pre>

#

Please login first before commenting.