mirror of
https://github.com/Hopiu/django-model-utils.git
synced 2026-04-18 18:30:58 +00:00
Add fix + tests for abstract manager inheritance issue with StatusModel
This commit is contained in:
parent
f56e26b5a9
commit
679af01f26
3 changed files with 57 additions and 1 deletions
|
|
@ -64,6 +64,11 @@ def add_status_query_managers(sender, **kwargs):
|
|||
"""
|
||||
if not issubclass(sender, StatusModel):
|
||||
return
|
||||
|
||||
if django.VERSION >= (1, 10):
|
||||
# First, get current manager name...
|
||||
default_manager = sender._meta.default_manager
|
||||
|
||||
for value, display in getattr(sender, 'STATUS', ()):
|
||||
if _field_exists(sender, value):
|
||||
raise ImproperlyConfigured(
|
||||
|
|
@ -73,6 +78,10 @@ def add_status_query_managers(sender, **kwargs):
|
|||
)
|
||||
sender.add_to_class(value, QueryManager(status=value))
|
||||
|
||||
if django.VERSION >= (1, 10):
|
||||
# ...then, put it back, as add_to_class is modifying the default manager!
|
||||
sender._meta.default_manager_name = default_manager.name
|
||||
|
||||
|
||||
def add_timeframed_query_manager(sender, **kwargs):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models
|
||||
from django.db.models import QuerySet
|
||||
from django.utils.encoding import python_2_unicode_compatible
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
|
|
@ -125,6 +126,28 @@ class StatusManagerAdded(StatusModel):
|
|||
)
|
||||
|
||||
|
||||
class StatusCustomQuerySet(QuerySet):
|
||||
def active_or_deleted(self):
|
||||
statuses = ['active', 'deleted']
|
||||
return self.filter(status__in=statuses)
|
||||
|
||||
|
||||
class AbstractStatusCustomManager(StatusModel):
|
||||
STATUS = Choices(
|
||||
("first_choice", _("First choice")),
|
||||
("second_choice", _("Second choice")),
|
||||
)
|
||||
|
||||
objects = StatusCustomQuerySet.as_manager()
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
|
||||
class StatusCustomManager(AbstractStatusCustomManager):
|
||||
title = models.CharField(max_length=50)
|
||||
|
||||
|
||||
class Post(models.Model):
|
||||
published = models.BooleanField(default=False)
|
||||
confirmed = models.BooleanField(default=False)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ from freezegun import freeze_time
|
|||
|
||||
from django.test.testcases import TestCase
|
||||
|
||||
from model_utils.tests.models import Status, StatusPlainTuple
|
||||
from model_utils.tests.models import Status, StatusPlainTuple, StatusCustomManager
|
||||
|
||||
|
||||
class StatusModelTests(TestCase):
|
||||
|
|
@ -44,3 +44,27 @@ class StatusModelPlainTupleTests(StatusModelTests):
|
|||
self.model = StatusPlainTuple
|
||||
self.on_hold = StatusPlainTuple.STATUS[2][0]
|
||||
self.active = StatusPlainTuple.STATUS[0][0]
|
||||
|
||||
|
||||
class StatusModelDefaultManagerTests(TestCase):
|
||||
|
||||
def test_default_manager_is_not_status_model_generated_ones(self):
|
||||
# Regression test for https://github.com/carljm/django-model-utils/issues/251
|
||||
# The logic behind order for managers seems to have changed in Django 1.10
|
||||
# and affects default manager.
|
||||
# This code was previously failing because the first custom manager (which filters
|
||||
# with first Choice value, here 'first_choice') generated by StatusModel was
|
||||
# considered as default manager...
|
||||
# This situation only happens when we define a model inheriting from an "abstract"
|
||||
# class which defines an "objects" manager.
|
||||
|
||||
StatusCustomManager.objects.create(status='first_choice')
|
||||
StatusCustomManager.objects.create(status='second_choice')
|
||||
StatusCustomManager.objects.create(status='second_choice')
|
||||
|
||||
# ...which made this count() equal to 1 (only 1 element with status='first_choice')...
|
||||
self.assertEqual(StatusCustomManager._default_manager.count(), 3)
|
||||
|
||||
# ...and this one equal to 0, because of 2 successive filters of 'first_choice'
|
||||
# (default manager) and 'second_choice' (explicit filter below).
|
||||
self.assertEqual(StatusCustomManager._default_manager.filter(status='second_choice').count(), 2)
|
||||
|
|
|
|||
Loading…
Reference in a new issue