Skip to content

Commit

Permalink
Merge pull request #93 from nyaruka/replace_auto_now
Browse files Browse the repository at this point in the history
Replace auto_now and auto_now_add with defaults which can be overridden
  • Loading branch information
rowanseymour authored Feb 24, 2017
2 parents 27547b3 + 038911b commit e52c339
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 14 deletions.
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,5 @@ celerybeat-schedule

*.DS_Store
.tox/
test-runner/env/
test-runner/smartmin
csv_imports/
!smartmin/csv_imports/
26 changes: 26 additions & 0 deletions smartmin/csv_imports/migrations/0004_auto_20170223_0917.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.4 on 2017-02-23 09:17
from __future__ import unicode_literals

from django.db import migrations, models
import django.utils.timezone


class Migration(migrations.Migration):

dependencies = [
('csv_imports', '0003_importtask_task_status'),
]

operations = [
migrations.AlterField(
model_name='importtask',
name='created_on',
field=models.DateTimeField(blank=True, default=django.utils.timezone.now, editable=False, help_text='When this item was originally created'),
),
migrations.AlterField(
model_name='importtask',
name='modified_on',
field=models.DateTimeField(blank=True, default=django.utils.timezone.now, editable=False, help_text='When this item was last modified'),
),
]
17 changes: 12 additions & 5 deletions smartmin/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import pytz
import six

from six import text_type
from django.conf import settings
from django.db import models
from django.utils import timezone
Expand Down Expand Up @@ -37,15 +36,23 @@ class SmartModel(models.Model):
created_by = models.ForeignKey(settings.AUTH_USER_MODEL,
related_name="%(app_label)s_%(class)s_creations",
help_text="The user which originally created this item")
created_on = models.DateTimeField(auto_now_add=True,
created_on = models.DateTimeField(default=timezone.now, editable=False, blank=True,
help_text="When this item was originally created")

modified_by = models.ForeignKey(settings.AUTH_USER_MODEL,
related_name="%(app_label)s_%(class)s_modifications",
help_text="The user which last modified this item")
modified_on = models.DateTimeField(auto_now=True,
modified_on = models.DateTimeField(default=timezone.now, editable=False, blank=True,
help_text="When this item was last modified")

def save(self, *args, **kwargs):
update_fields = kwargs.get('update_fields', None)

if (update_fields is None or 'modified_on' in update_fields) and not kwargs.pop('preserve_modified_on', False):
self.modified_on = timezone.now()

return super(SmartModel, self).save(*args, **kwargs)

class Meta:
abstract = True

Expand Down Expand Up @@ -240,12 +247,12 @@ def import_xls(cls, filename, user, import_params, log=None, import_results=None
num_errors += 1

except SmartImportRowError as e:
error_messages.append(dict(line=line_number+1, error=text_type(e)))
error_messages.append(dict(line=line_number+1, error=six.text_type(e)))

except Exception as e:
if log:
traceback.print_exc(100, log)
raise Exception("Line %d: %s\n\n%s" % (line_number, text_type(e), field_values))
raise Exception("Line %d: %s\n\n%s" % (line_number, six.text_type(e), field_values))
line_number += 1
# only care about the first sheet
break
Expand Down
36 changes: 36 additions & 0 deletions test_runner/blog/migrations/0003_auto_20170223_0917.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.4 on 2017-02-23 09:17
from __future__ import unicode_literals

from django.db import migrations, models
import django.utils.timezone


class Migration(migrations.Migration):

dependencies = [
('blog', '0002_post_uuid'),
]

operations = [
migrations.AlterField(
model_name='category',
name='created_on',
field=models.DateTimeField(blank=True, default=django.utils.timezone.now, editable=False, help_text='When this item was originally created'),
),
migrations.AlterField(
model_name='category',
name='modified_on',
field=models.DateTimeField(blank=True, default=django.utils.timezone.now, editable=False, help_text='When this item was last modified'),
),
migrations.AlterField(
model_name='post',
name='created_on',
field=models.DateTimeField(blank=True, default=django.utils.timezone.now, editable=False, help_text='When this item was originally created'),
),
migrations.AlterField(
model_name='post',
name='modified_on',
field=models.DateTimeField(blank=True, default=django.utils.timezone.now, editable=False, help_text='When this item was last modified'),
),
]
52 changes: 45 additions & 7 deletions test_runner/blog/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,20 +317,58 @@ def test_management(self):
self.assertEquals(12, authors.permissions.all().count())

def test_smart_model(self):
Post.objects.create(title="First Post", body="First Post body", order=1, tags="first",
created_by=self.author, modified_by=self.author)
p2 = Post.objects.create(title="Second Post", body="Second Post body", order=1, tags="second",
d1 = datetime(2016, 12, 31, 9, 20, 30, 123456, tzinfo=pytz.timezone("Africa/Kigali"))
d2 = datetime(2017, 1, 10, 10, 20, 30, 123456, tzinfo=pytz.timezone("Africa/Kigali"))
d3 = timezone.now()

p1 = Post.objects.create(title="First Post", body="First Post body", order=1, tags="first",
created_by=self.author, modified_by=self.author)
p2 = Post.objects.create(title="Second Post", body="Second Post body", order=1, tags="second",
created_on=d1, created_by=self.author,
modified_on=d2, modified_by=self.author)
p3 = Post(title="Third Post", body="Third Post body", order=1, tags="third",
created_on=d1, created_by=self.author,
modified_on=d2, modified_by=self.author)
p3.save(preserve_modified_on=True)

self.assertGreater(p1.created_on, d3) # defaults to current time
self.assertGreater(p1.modified_on, d3) # defaults to current time

self.assertEqual(p2.created_on, d1) # uses provided time
self.assertGreater(p2.modified_on, d3) # ignores provided time (equivalent to auto_now)

self.assertEqual(p3.created_on, d1) # uses provided time
self.assertEqual(p3.modified_on, d2) # uses provided time

d4 = timezone.now()

p1.save()
p2.save(update_fields=('title',))
p3.save(update_fields=('title', 'modified_on'))
self.post.save(preserve_modified_on=True)

self.assertLess(p1.created_on, d4) # not updated
self.assertGreater(p1.modified_on, d4) # updated by save with no args

self.assertLess(p2.created_on, d4) # not updated
self.assertLess(p2.modified_on, d4) # not updated because excluded by update_fields arg

self.assertLess(p3.created_on, d4) # not updated
self.assertGreater(p3.modified_on, d4) # updated because included by update_fields arg

self.assertLess(self.post.created_on, d4) # not updated
self.assertLess(self.post.modified_on, d4) # not updated because preserve_modified_on arg

self.assertEquals(3, Post.objects.all().count())
self.assertEquals(3, Post.active.all().count())
# test object managers
self.assertEqual(Post.objects.all().count(), 4)
self.assertEqual(Post.active.all().count(), 4)

# make p2 inactive
p2.is_active = False
p2.save()

self.assertEquals(3, Post.objects.all().count())
self.assertEquals(2, Post.active.all().count())
self.assertEqual(Post.objects.all().count(), 4)
self.assertEqual(Post.active.all().count(), 3)

def test_get_import_file_headers(self):
with open('test_runner/blog/test_files/posts.csv', 'rb') as open_file:
Expand Down

0 comments on commit e52c339

Please sign in to comment.