--HG--
extra : convert_revision : carl%40dirtcircle.com-20090730211136-ywu7dfqfmsodkc1x
This commit is contained in:
Carl Meyer 2009-07-30 17:11:36 -04:00
parent 7533a695fc
commit 7703512c7f
6 changed files with 97 additions and 6 deletions

View file

@ -2,3 +2,8 @@
django-model-utils changelog
============================
v0.3.0
------
* Added ``QueryManager``

View file

@ -4,8 +4,8 @@ django-model-utils
Django model mixins and utilities.
InheritanceCastModel
====================
models.InheritanceCastModel
===========================
This abstract base class can be inherited by the root (parent) model
in a model-inheritance tree. It allows each model in the tree to
@ -43,8 +43,34 @@ return an instance of the proper subtype, ``Restaurant`` or ``Bar``::
QuerySet subclass that could reduce this to k queries, where there
are k subtypes in the inheritance tree.
TimeStampedModel
================
models.TimeStampedModel
=======================
This abstract base class just provides self-updating ``created`` and
``modified`` fields on any model that inherits it.
managers.QueryManager
=====================
Many custom model managers do nothing more than return a QuerySet that
is filtered in some way. ``QueryManager`` allows you to express this
pattern with a minimum of boilerplate::
from django.db import models
from model_utils.managers import QueryManager
class Post(models.Model):
...
published = models.BooleanField()
pub_date = models.DateField()
...
objects = models.Manager()
public = QueryManager(published=True).order_by('-pub_date')
The kwargs passed to ``QueryManager`` will be passed as-is to the
``QuerySet.filter()`` method. You can also pass a ``Q`` object to
``QueryManager`` to express more complex conditions. Note that you can
set the ordering of the ``QuerySet`` returned by the ``QueryManager``
by chaining a call to ``.order_by()`` on the ``QueryManager`` (this is
not required).

20
model_utils/managers.py Normal file
View file

@ -0,0 +1,20 @@
from django.db import models
class QueryManager(models.Manager):
def __init__(self, *args, **kwargs):
if args:
self._q = args[0]
else:
self._q = models.Q(**kwargs)
super(QueryManager, self).__init__()
def order_by(self, *args):
self._order_by = args
return self
def get_query_set(self):
qs = super(QueryManager, self).get_query_set().filter(self._q)
if hasattr(self, '_order_by'):
return qs.order_by(*self._order_by)
return qs

View file

@ -1,6 +1,8 @@
from django.db import models
from model_utils.models import InheritanceCastModel, TimeStampedModel
from model_utils.managers import QueryManager
class InheritParent(InheritanceCastModel):
pass
@ -10,3 +12,17 @@ class InheritChild(InheritParent):
class TimeStamp(TimeStampedModel):
pass
class Post(models.Model):
published = models.BooleanField()
confirmed = models.BooleanField()
order = models.IntegerField()
objects = models.Manager()
public = QueryManager(published=True)
public_confirmed = QueryManager(models.Q(published=True) &
models.Q(confirmed=True))
public_reversed = QueryManager(published=True).order_by('-order')
class Meta:
ordering = ('order',)

View file

@ -1,7 +1,8 @@
from django.test import TestCase
from django.contrib.contenttypes.models import ContentType
from model_utils.tests.models import InheritParent, InheritChild, TimeStamp
from model_utils.tests.models import InheritParent, InheritChild, TimeStamp, \
Post
class InheritanceCastModelTests(TestCase):
def setUp(self):
@ -32,3 +33,26 @@ class TimeStampedModelTests(TestCase):
t2 = TimeStamp.objects.create()
t1.save()
self.assert_(t2.modified < t1.modified)
class QueryManagerTests(TestCase):
def setUp(self):
data = ((True, True, 0),
(True, False, 4),
(False, False, 2),
(False, True, 3),
(True, True, 1),
(True, False, 5))
for p, c, o in data:
Post.objects.create(published=p, confirmed=c, order=o)
def testPassingKwargs(self):
qs = Post.public.all()
self.assertEquals([p.order for p in qs], [0, 1, 4, 5])
def testPassingQ(self):
qs = Post.public_confirmed.all()
self.assertEquals([p.order for p in qs], [0, 1])
def testOrdering(self):
qs = Post.public_reversed.all()
self.assertEquals([p.order for p in qs], [5, 4, 1, 0])

View file

@ -2,7 +2,7 @@ from setuptools import setup, find_packages
setup(
name='django-model-utils',
version='0.2.1',
version='0.3.0',
description='Django model mixins and utilities',
long_description=open('README.txt').read(),
author='Carl Meyer',