Opened 11 years ago

Closed 11 years ago

Last modified 11 years ago

#21312 closed Uncategorized (invalid)

models.DateTimeField with default=now: South migration fails

Reported by: Mathieu Agopian Owned by: nobody
Component: Database layer (models, ORM) Version: 1.6-beta-1
Severity: Normal Keywords:
Cc: pronik Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

This is a problem that didn't happen on django1.6b4, but does on django1.6c1:

Here's a snippet of the model:

from django.utils.timezone import now


@python_2_unicode_compatible
class User(AbstractBaseUser, PermissionsMixin):
    """TopChretien User, identified by its email."""
    ...
    last_modified = models.DateTimeField(
        _('last modification'), default=now, editable=False)
    ...

Here's the auto migration created by South when adding this new field to the model:

import datetime
...

class Migration(SchemaMigration):

    def forwards(self, orm):
        # Adding field 'User.last_modified'
        db.add_column(u'user_user', 'last_modified',
                      self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now),
                      keep_default=False)

And here's the result of running "manage.py migrate user" on django1.6b4:

$ ./manage.py migrate user
Running migrations for user:
 - Migrating forwards to 0007_auto__add_field_user_last_modified__add_field_user_moderation_date__ad.
 > user:0007_auto__add_field_user_last_modified__add_field_user_moderation_date__ad
/home/mathieu/.virtualenvs/top/lib/python2.7/site-packages/django/db/models/fields/__init__.py:901: RuntimeWarning: DateTimeField received a naive datetime (2013-10-23 15:50:11.448018) while time zone support is active.
  RuntimeWarning)

 - Loading initial data for user.
Installed 0 object(s) from 0 fixture(s)

And now on django1.6c1 (only the end of stacktrace, for readability, please let me know if you need more):

  File "/home/mathieu/Dropbox/dev/topchretien/web/topchretien/user/migrations/0007_auto__add_field_user_moderation_date__add_field_user_moderator__add_fi.py", line 14, in forwards
    keep_default=False)
  File "/home/mathieu/.virtualenvs/top/lib/python2.7/site-packages/south/db/generic.py", line 47, in _cache_clear
    return func(self, table, *args, **opts)
  File "/home/mathieu/.virtualenvs/top/lib/python2.7/site-packages/south/db/generic.py", line 411, in add_column
    sql = self.column_sql(table_name, name, field)
  File "/home/mathieu/.virtualenvs/top/lib/python2.7/site-packages/south/db/generic.py", line 706, in column_sql
    default = field.get_db_prep_save(default, connection=self._get_connection())
  File "/home/mathieu/.virtualenvs/top/lib/python2.7/site-packages/django/db/models/fields/__init__.py", line 350, in get_db_prep_save
    prepared=False)
  File "/home/mathieu/.virtualenvs/top/lib/python2.7/site-packages/django/db/models/fields/__init__.py", line 911, in get_db_prep_value
    value = self.get_prep_value(value)
  File "/home/mathieu/.virtualenvs/top/lib/python2.7/site-packages/django/db/models/fields/__init__.py", line 902, in get_prep_value
    (self.model.__name__, self.name, value),
AttributeError: 'DateTimeField' object has no attribute 'model'

The solution I used was to modify the South migration to get rid of the warning (in Django1.6b4) and make it work correctly (in django1.6c1):

import django.utils.timezone
...

class Migration(SchemaMigration):

    def forwards(self, orm):
        # Adding field 'User.last_modified'
        db.add_column(u'user_user', 'last_modified',
                      self.gf('django.db.models.fields.DateTimeField')(default=django.utils.timezone.now),
                      keep_default=False)

Change History (7)

comment:1 by Marc Tamlyn, 11 years ago

Severity: NormalRelease blocker
Version: 1.41.6-beta-1

I haven't checked this but marking as a release block as assuming it is repeatable it certainly is a problem.

Do you perhaps have a minimal project set up to reproduce this? If not, could you perhaps try to use git bisect to identify where between the tags it broke? This would help us identify a fix faster.

comment:2 by Anssi Kääriäinen, 11 years ago

I've taken a quick look at this. This was introduced by ddff6522fa72aacc7475ba5cd4bf8683ff12b8c7. The problem is that South doesn't assign the field to any model. In Django self.model should always exists (or at least always after app-loading).

I am not sure if this should be fixed in Django or in South. We can definitely say that South relies on non-public usage of fields (after all the only public way to use fields is to assign them to models in model definition, and that means they will have self.model set). OTOH it seems pretty simple to fix this in Django... I have generally favoured "private API is private" -approach, so I am slightly in favour of that interpretation.

comment:3 by Shai Berger, 11 years ago

Component: UncategorizedDatabase layer (models, ORM)
Severity: Release blockerNormal

Based on Anssi's analysis, this is not a blocker for Django. Not sure it is even a bug in Django.

comment:4 by pronik, 11 years ago

Cc: pronik added

comment:5 by Andrew Godwin, 11 years ago

Resolution: invalid
Status: newclosed

This is definitely a bug in South. Closing as invalid.

comment:6 by jvzammit@…, 11 years ago

Did anyone report this in South? Thanks.

in reply to:  6 comment:7 by jvzammit@…, 11 years ago

Replying to jvzammit@…:

Did anyone report this in South? Thanks.

Please disregard my question; upgrading from south 0.8.2 to 0.8.3 solved the problem.

Note: See TracTickets for help on using tickets.
Back to Top