Anssi Kääriäinen f4132140f5 [1.5.x] Fixed #19652 -- Fixed .none() regression in related fields
The regression was caused by using .none() when querying for related
models, and the origin field's value was None. This resulted in missing
custom related manager subclass as .none() returns plain QuerySet.

This isn't backport from master, in master .none() correctly preserves
the queryset's class.

Patch provided by Simon Charette, with some minor polish by committer.
2013-01-23 08:26:34 +02:00

87 lines
2.4 KiB
Python

"""
23. Giving models a custom manager
You can use a custom ``Manager`` in a particular model by extending the base
``Manager`` class and instantiating your custom ``Manager`` in your model.
There are two reasons you might want to customize a ``Manager``: to add extra
``Manager`` methods, and/or to modify the initial ``QuerySet`` the ``Manager``
returns.
"""
from __future__ import unicode_literals
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
# An example of a custom manager called "objects".
class PersonManager(models.Manager):
def get_fun_people(self):
return self.filter(fun=True)
@python_2_unicode_compatible
class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
fun = models.BooleanField()
objects = PersonManager()
def __str__(self):
return "%s %s" % (self.first_name, self.last_name)
# An example of a custom manager that sets get_query_set().
class PublishedBookManager(models.Manager):
def get_query_set(self):
return super(PublishedBookManager, self).get_query_set().filter(is_published=True)
@python_2_unicode_compatible
class Book(models.Model):
title = models.CharField(max_length=50)
author = models.CharField(max_length=30)
is_published = models.BooleanField()
published_objects = PublishedBookManager()
authors = models.ManyToManyField(Person, related_name='books')
def __str__(self):
return self.title
# An example of providing multiple custom managers.
class FastCarManager(models.Manager):
def get_query_set(self):
return super(FastCarManager, self).get_query_set().filter(top_speed__gt=150)
@python_2_unicode_compatible
class Car(models.Model):
name = models.CharField(max_length=10)
mileage = models.IntegerField()
top_speed = models.IntegerField(help_text="In miles per hour.")
cars = models.Manager()
fast_cars = FastCarManager()
def __str__(self):
return self.name
# Bug #19652
class ObjectQuerySet(models.query.QuerySet):
pass
class ObjectManager(models.Manager):
use_for_related_fields = True
def get_query_set(self):
return ObjectQuerySet(self.model, using=self._db)
class RelatedObject(models.Model):
pass
class Object(models.Model):
related = models.ForeignKey(RelatedObject, related_name='objs')
objects = ObjectManager()