Commits

Jannis Leidel committed 9f04e31

Fixed bug which prevented the StatusModel and TimeframedModel to get the appropriate QueryManager instances added dynamically before instantiation.

Comments (0)

Files changed (3)

model_utils/models.py

 from django.contrib.contenttypes.models import ContentType
 from django.utils.translation import ugettext_lazy as _
 from django.db.models.fields import FieldDoesNotExist
+from django.core.exceptions import ImproperlyConfigured
 
 from model_utils.managers import QueryManager
 from model_utils.fields import AutoCreatedField, AutoLastModifiedField, \
     start = models.DateTimeField(_('start'), null=True, blank=True)
     end = models.DateTimeField(_('end'), null=True, blank=True)
 
-    def __init__(self, *args, **kwargs):
-        super(TimeFramedModel, self).__init__(*args, **kwargs)
-        try:
-            self._meta.get_field('timeframed')
-            raise ValueError("Model '%s' has a field named 'timeframed' which "
-                             "conflicts with the TimeFramedModel manager." % self.__name__)
-        except FieldDoesNotExist:
-            pass
-        self.__class__.add_to_class('timeframed', QueryManager(
-            (models.Q(start__lte=datetime.now()) | models.Q(start__isnull=True)) &
-            (models.Q(end__gte=datetime.now()) | models.Q(end__isnull=True))
-        ))
-
     class Meta:
         abstract = True
 
     status = StatusField(_('status'))
     status_changed = MonitorField(_('status changed'), monitor='status')
 
-    def __init__(self, *args, **kwargs):
-        super(StatusModel, self).__init__(*args, **kwargs)
-        for value, name in getattr(self, 'STATUS', ()):
-            try:
-                self._meta.get_field(name)
-                from django.core.exceptions import ImproperlyConfigured
-                raise ImproperlyConfigured("StatusModel: Model '%s' has a field named '%s' which "
-                                           "conflicts with a status of the same name."
-                                           % (self.__name__, name))
-            except FieldDoesNotExist:
-                pass
-            self.__class__.add_to_class(value, QueryManager(status=value))
-
     class Meta:
         abstract = True
 
+def add_status_query_managers(sender, **kwargs):
+    """
+    Add a Querymanager for each status item dynamically.
+    """
+    if not issubclass(sender, StatusModel):
+        return
+    for value, name in getattr(sender, 'STATUS', ()):
+        try:
+            sender._meta.get_field(name)
+            raise ImproperlyConfigured("StatusModel: Model '%s' has a field "
+                                       "named '%s' which conflicts with a "
+                                       "status of the same name."
+                                       % (sender.__name__, name))
+        except FieldDoesNotExist:
+            pass
+        sender.add_to_class(value, QueryManager(status=value))
+
+def add_timeframed_query_manager(sender, **kwargs):
+    """
+    Addds a QueryManager for a specific timeframe
+    """
+    if not issubclass(sender, TimeFramedModel):
+        return
+    try:
+        sender._meta.get_field('timeframed')
+        raise ValueError("Model '%s' has a field named 'timeframed' which "
+                         "conflicts with the TimeFramedModel manager." % sender.__name__)
+    except FieldDoesNotExist:
+        pass
+    sender.add_to_class('timeframed', QueryManager(
+        (models.Q(start__lte=datetime.now) | models.Q(start__isnull=True)) &
+        (models.Q(end__gte=datetime.now) | models.Q(end__isnull=True))
+    ))
+
+
+models.signals.class_prepared.connect(add_status_query_managers)
+models.signals.class_prepared.connect(add_timeframed_query_manager)

model_utils/tests/models.py

 class TimeFrame(TimeFramedModel):
     pass
 
+class TimeFrameManagerAdded(TimeFramedModel):
+    pass
+
 class Monitored(models.Model):
     name = models.CharField(max_length=25)
     name_changed = MonitorField(monitor='name')
         ('on_hold', _('on hold')),
     )
 
+class StatusManagerAdded(StatusModel):
+    STATUS = (
+        ('active', _('active')),
+        ('deleted', _('deleted')),
+        ('on_hold', _('on hold')),
+    )
+
 class Post(models.Model):
     published = models.BooleanField()
     confirmed = models.BooleanField()

model_utils/tests/tests.py

 
 from model_utils import ChoiceEnum, Choices
 from model_utils.fields import get_excerpt
-from model_utils.tests.models import InheritParent, InheritChild, TimeStamp, \
-    Post, Article, Status, StatusPlainTuple, TimeFrame, Monitored
+from model_utils.managers import QueryManager
+from model_utils.tests.models import (InheritParent, InheritChild, TimeStamp,
+    Post, Article, Status, StatusPlainTuple, TimeFrame, Monitored,
+    StatusManagerAdded, TimeFrameManagerAdded)
 
 
 class GetExcerptTests(TestCase):
                                  end=self.now+timedelta(days=1))
         self.assertEquals(TimeFrame.timeframed.count(), 1)
 
+class TimeFrameManagerAddedTests(TestCase):
+
+    def test_manager_avaiable(self):
+        self.assert_(isinstance(TimeFrameManagerAdded.timeframed, QueryManager))
 
 class StatusModelTests(TestCase):
     def setUp(self):
         self.on_hold = StatusPlainTuple.STATUS[2][0]
         self.active = StatusPlainTuple.STATUS[0][0]
 
+class StatusManagerAddedTests(TestCase):
+
+    def test_manager_avaiable(self):
+        self.assert_(isinstance(StatusManagerAdded.active, QueryManager))
 
 class QueryManagerTests(TestCase):
     def setUp(self):