0

I have just upgraded my Django 1.6.5 project to Django 1.7.1. I followed the steps documented to move from South to Django 1.7.1 and it works perfectly.

The issue I have is when I run "python manage.py test" on my project, it fails with the error:

Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/home/mark/.virtualenvs/clippy/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 385, in execute_from_command_line
    utility.execute()
  File "/home/mark/.virtualenvs/clippy/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 377, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/mark/.virtualenvs/clippy/local/lib/python2.7/site-packages/django/core/management/commands/test.py", line 50, in run_from_argv
    super(Command, self).run_from_argv(argv)
  File "/home/mark/.virtualenvs/clippy/local/lib/python2.7/site-packages/django/core/management/base.py", line 288, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/home/mark/.virtualenvs/clippy/local/lib/python2.7/site-packages/django/core/management/commands/test.py", line 71, in execute
    super(Command, self).execute(*args, **options)
  File "/home/mark/.virtualenvs/clippy/local/lib/python2.7/site-packages/django/core/management/base.py", line 338, in execute
    output = self.handle(*args, **options)
  File "/home/mark/.virtualenvs/clippy/local/lib/python2.7/site-packages/django/core/management/commands/test.py", line 88, in handle
    failures = test_runner.run_tests(test_labels)
  File "/home/mark/.virtualenvs/clippy/local/lib/python2.7/site-packages/django/test/runner.py", line 147, in run_tests
    old_config = self.setup_databases()
  File "/home/mark/.virtualenvs/clippy/local/lib/python2.7/site-packages/django/test/runner.py", line 109, in setup_databases
    return setup_databases(self.verbosity, self.interactive, **kwargs)
  File "/home/mark/.virtualenvs/clippy/local/lib/python2.7/site-packages/django/test/runner.py", line 299, in setup_databases
    serialize=connection.settings_dict.get("TEST", {}).get("SERIALIZE", True),
  File "/home/mark/.virtualenvs/clippy/local/lib/python2.7/site-packages/django/db/backends/creation.py", line 377, in create_test_db
    test_flush=True,
  File "/home/mark/.virtualenvs/clippy/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 115, in call_command
    return klass.execute(*args, **defaults)
  File "/home/mark/.virtualenvs/clippy/local/lib/python2.7/site-packages/django/core/management/base.py", line 338, in execute
    output = self.handle(*args, **options)
  File "/home/mark/.virtualenvs/clippy/local/lib/python2.7/site-packages/django/core/management/commands/migrate.py", line 160, in handle
    executor.migrate(targets, plan, fake=options.get("fake", False))
  File "/home/mark/.virtualenvs/clippy/local/lib/python2.7/site-packages/django/db/migrations/executor.py", line 63, in migrate
    self.apply_migration(migration, fake=fake)
  File "/home/mark/.virtualenvs/clippy/local/lib/python2.7/site-packages/django/db/migrations/executor.py", line 97, in apply_migration
    migration.apply(project_state, schema_editor)
  File "/home/mark/.virtualenvs/clippy/local/lib/python2.7/site-packages/django/db/migrations/migration.py", line 107, in apply
    operation.database_forwards(self.app_label, schema_editor, project_state, new_state)
  File "/home/mark/.virtualenvs/clippy/local/lib/python2.7/site-packages/django/db/migrations/operations/models.py", line 36, in database_forwards
    schema_editor.create_model(model)
  File "/home/mark/.virtualenvs/clippy/local/lib/python2.7/site-packages/django/db/backends/schema.py", line 209, in create_model
    definition, extra_params = self.column_sql(model, field)
  File "/home/mark/.virtualenvs/clippy/local/lib/python2.7/site-packages/django/db/backends/schema.py", line 121, in column_sql
    default_value = self.effective_default(field)
  File "/home/mark/.virtualenvs/clippy/local/lib/python2.7/site-packages/django/db/backends/schema.py", line 184, in effective_default
    default = field.get_db_prep_save(default, self.connection)
  File "/home/mark/.virtualenvs/clippy/local/lib/python2.7/site-packages/django/db/models/fields/__init__.py", line 627, in get_db_prep_save
    prepared=False)
  File "/home/mark/projects/clippy/core/fields.py", line 21, in get_db_prep_value
    return int(time.mktime(value.timetuple()))
AttributeError: 'NoneType' object has no attribute 'timetuple'

I believe this is as a result of a custom field I use to store date/time fields as timestamp integers in the database. The code for this is:

class UnixDateTimeField(models.DateTimeField):
    __metaclass__ = models.SubfieldBase

    def get_internal_type(self):
        return 'PositiveIntegerField'

    def to_python(self, value):
        if value is None or isinstance(value, datetime):
            return value
        if isinstance(value, date):
            return datetime(value.year, value.month, value.day, 0, 0, 0, 0, utc)
        return datetime.utcfromtimestamp(float(value)).replace(tzinfo=utc)

    def get_db_prep_value(self, value, connection, prepared=False):
        return int(time.mktime(value.timetuple()))

    def value_to_string(self, obj):
        value = self._get_val_from_obj(obj)
        return self.to_python(value).strftime('%Y-%m-%d %H:%M:%S %Z')

This happens even if I remove ALL unit tests from my project. Does anyone know what is causing this? It worked fine before upgrading to Django 1.7.1.

LondonAppDev
  • 8,501
  • 8
  • 60
  • 87
  • It is clear that you are getting None in value when your are calling custom method get_db_prep_value. – Tanveer Alam Nov 30 '14 at 10:55
  • Thanks. That's true, and the question is why? Why is it that it works fine when using the custom field on the models, it works fine on Django 6.5 but it doesn't work when running tests on Django 1.7. This is what I would like to figure out. – LondonAppDev Dec 02 '14 at 08:28

2 Answers2

0

I also have some kind of errors using Django Custom Fields and I think problem is the around the migration system of Django.

Try to squash / remove the migrations ( https://docs.djangoproject.com/en/1.7/topics/migrations/#squashing-migrations )

PaytoN
  • 154
  • 10
  • Thanks for the reply. My migrations are already condensed into one file so I don't think squashing will make a difference. – LondonAppDev Dec 02 '14 at 08:26
0

I solved this by adding the following to the get_db_prep_value() method in my field:

if value is None:
    return value

So the total field becomes:

class UnixDateTimeField(models.DateTimeField):
    __metaclass__ = models.SubfieldBase

    def get_internal_type(self):
        return 'PositiveIntegerField'

    def to_python(self, value):
        if value is None or isinstance(value, datetime):
            return value
        if isinstance(value, date):
            return datetime(value.year, value.month, value.day, 0, 0, 0, 0, utc)
        return datetime.utcfromtimestamp(float(value)).replace(tzinfo=utc)

    def get_db_prep_value(self, value, connection, prepared=False):

        if value is None:
            return value

        return int(time.mktime(value.timetuple()))

    def value_to_string(self, obj):
        value = self._get_val_from_obj(obj)
        return self.to_python(value).strftime('%Y-%m-%d %H:%M:%S %Z')

This solved this issue and now the tests work.

LondonAppDev
  • 8,501
  • 8
  • 60
  • 87