2
0

models.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. """
  2. Giving models a custom manager
  3. You can use a custom ``Manager`` in a particular model by extending the base
  4. ``Manager`` class and instantiating your custom ``Manager`` in your model.
  5. There are two reasons you might want to customize a ``Manager``: to add extra
  6. ``Manager`` methods, and/or to modify the initial ``QuerySet`` the ``Manager``
  7. returns.
  8. """
  9. from __future__ import unicode_literals
  10. from django.contrib.contenttypes.fields import (
  11. GenericForeignKey, GenericRelation,
  12. )
  13. from django.db import models
  14. from django.utils.encoding import python_2_unicode_compatible
  15. class PersonManager(models.Manager):
  16. def get_fun_people(self):
  17. return self.filter(fun=True)
  18. class PublishedBookManager(models.Manager):
  19. def get_queryset(self):
  20. return super(PublishedBookManager, self).get_queryset().filter(is_published=True)
  21. class CustomQuerySet(models.QuerySet):
  22. def filter(self, *args, **kwargs):
  23. queryset = super(CustomQuerySet, self).filter(fun=True)
  24. queryset._filter_CustomQuerySet = True
  25. return queryset
  26. def public_method(self, *args, **kwargs):
  27. return self.all()
  28. def _private_method(self, *args, **kwargs):
  29. return self.all()
  30. def optout_public_method(self, *args, **kwargs):
  31. return self.all()
  32. optout_public_method.queryset_only = True
  33. def _optin_private_method(self, *args, **kwargs):
  34. return self.all()
  35. _optin_private_method.queryset_only = False
  36. class BaseCustomManager(models.Manager):
  37. def __init__(self, arg):
  38. super(BaseCustomManager, self).__init__()
  39. self.init_arg = arg
  40. def filter(self, *args, **kwargs):
  41. queryset = super(BaseCustomManager, self).filter(fun=True)
  42. queryset._filter_CustomManager = True
  43. return queryset
  44. def manager_only(self):
  45. return self.all()
  46. CustomManager = BaseCustomManager.from_queryset(CustomQuerySet)
  47. class CustomInitQuerySet(models.QuerySet):
  48. # QuerySet with an __init__() method that takes an additional argument.
  49. def __init__(self, custom_optional_arg=None, model=None, query=None, using=None, hints=None):
  50. super(CustomInitQuerySet, self).__init__(model=model, query=query, using=using, hints=hints)
  51. class DeconstructibleCustomManager(BaseCustomManager.from_queryset(CustomQuerySet)):
  52. def __init__(self, a, b, c=1, d=2):
  53. super(DeconstructibleCustomManager, self).__init__(a)
  54. class FunPeopleManager(models.Manager):
  55. def get_queryset(self):
  56. return super(FunPeopleManager, self).get_queryset().filter(fun=True)
  57. class BoringPeopleManager(models.Manager):
  58. def get_queryset(self):
  59. return super(BoringPeopleManager, self).get_queryset().filter(fun=False)
  60. @python_2_unicode_compatible
  61. class Person(models.Model):
  62. first_name = models.CharField(max_length=30)
  63. last_name = models.CharField(max_length=30)
  64. fun = models.BooleanField(default=False)
  65. favorite_book = models.ForeignKey('Book', models.SET_NULL, null=True, related_name='favorite_books')
  66. favorite_thing_type = models.ForeignKey('contenttypes.ContentType', models.SET_NULL, null=True)
  67. favorite_thing_id = models.IntegerField(null=True)
  68. favorite_thing = GenericForeignKey('favorite_thing_type', 'favorite_thing_id')
  69. objects = PersonManager()
  70. fun_people = FunPeopleManager()
  71. boring_people = BoringPeopleManager()
  72. custom_queryset_default_manager = CustomQuerySet.as_manager()
  73. custom_queryset_custom_manager = CustomManager('hello')
  74. custom_init_queryset_manager = CustomInitQuerySet.as_manager()
  75. def __str__(self):
  76. return "%s %s" % (self.first_name, self.last_name)
  77. @python_2_unicode_compatible
  78. class FunPerson(models.Model):
  79. first_name = models.CharField(max_length=30)
  80. last_name = models.CharField(max_length=30)
  81. fun = models.BooleanField(default=True)
  82. favorite_book = models.ForeignKey(
  83. 'Book',
  84. models.SET_NULL,
  85. null=True,
  86. related_name='fun_people_favorite_books',
  87. )
  88. favorite_thing_type = models.ForeignKey('contenttypes.ContentType', models.SET_NULL, null=True)
  89. favorite_thing_id = models.IntegerField(null=True)
  90. favorite_thing = GenericForeignKey('favorite_thing_type', 'favorite_thing_id')
  91. objects = FunPeopleManager()
  92. def __str__(self):
  93. return "%s %s" % (self.first_name, self.last_name)
  94. @python_2_unicode_compatible
  95. class Book(models.Model):
  96. title = models.CharField(max_length=50)
  97. author = models.CharField(max_length=30)
  98. is_published = models.BooleanField(default=False)
  99. published_objects = PublishedBookManager()
  100. authors = models.ManyToManyField(Person, related_name='books')
  101. fun_authors = models.ManyToManyField(FunPerson, related_name='books')
  102. favorite_things = GenericRelation(Person,
  103. content_type_field='favorite_thing_type', object_id_field='favorite_thing_id')
  104. fun_people_favorite_things = GenericRelation(FunPerson,
  105. content_type_field='favorite_thing_type', object_id_field='favorite_thing_id')
  106. def __str__(self):
  107. return self.title
  108. class FastCarManager(models.Manager):
  109. def get_queryset(self):
  110. return super(FastCarManager, self).get_queryset().filter(top_speed__gt=150)
  111. @python_2_unicode_compatible
  112. class Car(models.Model):
  113. name = models.CharField(max_length=10)
  114. mileage = models.IntegerField()
  115. top_speed = models.IntegerField(help_text="In miles per hour.")
  116. cars = models.Manager()
  117. fast_cars = FastCarManager()
  118. def __str__(self):
  119. return self.name
  120. class RestrictedManager(models.Manager):
  121. def get_queryset(self):
  122. return super(RestrictedManager, self).get_queryset().filter(is_public=True)
  123. @python_2_unicode_compatible
  124. class RelatedModel(models.Model):
  125. name = models.CharField(max_length=50)
  126. def __str__(self):
  127. return self.name
  128. @python_2_unicode_compatible
  129. class RestrictedModel(models.Model):
  130. name = models.CharField(max_length=50)
  131. is_public = models.BooleanField(default=False)
  132. related = models.ForeignKey(RelatedModel, models.CASCADE)
  133. objects = RestrictedManager()
  134. plain_manager = models.Manager()
  135. def __str__(self):
  136. return self.name
  137. @python_2_unicode_compatible
  138. class OneToOneRestrictedModel(models.Model):
  139. name = models.CharField(max_length=50)
  140. is_public = models.BooleanField(default=False)
  141. related = models.OneToOneField(RelatedModel, models.CASCADE)
  142. objects = RestrictedManager()
  143. plain_manager = models.Manager()
  144. def __str__(self):
  145. return self.name
  146. class AbstractPerson(models.Model):
  147. abstract_persons = models.Manager()
  148. objects = models.CharField(max_length=30)
  149. class Meta:
  150. abstract = True
  151. class PersonFromAbstract(AbstractPerson):
  152. pass