Commits

Anonymous committed b8671c3

added TimeStampedModel

  • Participants
  • Parent commits b6e99b0

Comments (0)

Files changed (5)

 instances back, even for objects that are "really" ``Restaurant`` or
 ``Bar``.  If you have ``Place`` inherit from ``InheritanceCastModel``,
 you can just call the ``cast()`` method on each ``Place`` and it will
-return an instance of the proper subtype, ``Restaurant`` or ``Bar``.
+return an instance of the proper subtype, ``Restaurant`` or ``Bar``::
+
+    from model_utils.models import InheritanceCastModel
+
+    class Place(InheritanceCastModel):
+        ...
+    
+    class Restaurant(Place):
+        ...
+
+    nearby_places = Place.objects.filter(location='here')
+    for place in nearby_places:
+        restaurant_or_bar = place.cast()
+        ...
 
 .. note:: 
     This is inefficient for large querysets, as it results in n
     queries to the subtype tables.  It would be possible to write a
     QuerySet subclass that could reduce this to k queries, where there
     are k subtypes in the inheritance tree.
+
+TimeStampedModel
+================
+
+This abstract base class just provides self-updating ``created`` and
+``modified`` fields on any model that inherits it.

File model_utils/fields.py

+from datetime import datetime
+
+from django.db import models
+
+class AutoCreatedField (models.DateTimeField):
+    """
+    A DateTimeField that automatically populates itself at
+    object creation.
+
+    By default, sets editable=False, default=datetime.now.
+
+    """
+    def __init__ (self, *args, **kwargs):
+        kwargs.setdefault('editable', False)
+        kwargs.setdefault('default', datetime.now)
+        super(AutoCreatedField, self).__init__(*args, **kwargs)
+
+class AutoLastModifiedField (AutoCreatedField):
+    """
+    A DateTimeField that updates itself on each save() of the model.
+
+    By default, sets editable=False and default=datetime.now.
+    
+    """
+    def pre_save (self, model_instance, add):
+        value = datetime.now()
+        setattr(model_instance, self.attname, value)
+        return value    
+    

File model_utils/models.py

 from django.db import models
 from django.contrib.contenttypes.models import ContentType
 
+from model_utils.fields import AutoCreatedField, AutoLastModifiedField
+
 class InheritanceCastModel(models.Model):
     """
     An abstract base class that provides a ``real_type`` FK to ContentType.
         
     class Meta:
         abstract = True
+
+
+class TimeStampedModel (models.Model):
+    """
+    An abstract base class model that provides self-updating
+    ``created`` and ``modified`` fields.
+
+    """
+    created = AutoCreatedField()
+    modified = AutoLastModifiedField()
+
+    class Meta:
+        abstract = True
+

File model_utils/tests/models.py

 from django.db import models
 
-from model_utils.models import InheritanceCastModel
+from model_utils.models import InheritanceCastModel, TimeStampedModel
 
 class InheritParent(InheritanceCastModel):
     pass
 class InheritChild(InheritParent):
     pass
 
+class TimeStamp(TimeStampedModel):
+    pass

File model_utils/tests/tests.py

 from django.test import TestCase
 from django.contrib.contenttypes.models import ContentType
 
-from model_utils.tests.models import InheritParent, InheritChild
+from model_utils.tests.models import InheritParent, InheritChild, TimeStamp
 
 class InheritanceCastModelTests(TestCase):
     def setUp(self):
     def testCast(self):
         obj = InheritParent.objects.get(pk=self.child.pk).cast()
         self.assertEquals(obj.__class__, InheritChild)
+
+
+class TimeStampedModelTests(TestCase):
+    def testCreated(self):
+        t1 = TimeStamp.objects.create()
+        t2 = TimeStamp.objects.create()
+        self.assert_(t2.created > t1.created)
+
+    def testModified(self):
+        t1 = TimeStamp.objects.create()
+        t2 = TimeStamp.objects.create()
+        t1.save()
+        self.assert_(t2.modified < t1.modified)