Search code examples
pythonmysqldjangodatefield

Django 1.8 change datefield to DateTimeField


I use Django 1.8

I Have model.py, like this

class Product(models.Model):

    name = models.CharField(max_length=150)
    created_at = models.DateField(auto_now_add = True)
    modified_at = models.DateField(auto_now = True)

MySQL have a table 'created_at' and 'modified_at' who has data like this "2015-11-02" I would like change data to "2015-11-02 14:54:22"

I change models.py to this

class Product(models.Model):

    name = models.CharField(max_length=150)
    created_at = models.DateTimeField(auto_now_add = True)
    modified_at = models.DateTimeField(auto_now = True)

Then I run migrations in console

python manage.py makemigrations
python manage.py migrate

But nothing happened. Data in MySQL Tables not change, and when I add new information, in MySQL add time in old patterns "2015-11-02"

How I change them?

PS to Lego Stormtroopr

Thanx, I read Django tutorial, and wrote this code

from __future__ import unicode_literals
from django.db import migrations, models
import datetime

def add_time_to_date(apps, schema_editor):
    datetables = apps.get_model("product", "Product")
    delta = datetime.timedelta(hours=1)
    for x in datetables.objects.all():
        x.created_at = x.created_at + delta
        x.modified_at = x.modified_at + delta
        x.save()


class Migration(migrations.Migration):
    dependencies = [
        ('product', '0003_auto_20151110_1726'),
    ]

    operations = [
        migrations.RunPython(add_time_to_date),
     ]

After that, i run

   python manage.py migrate

Console wrote this:

    Operations to perform:
      Synchronize unmigrated apps: staticfiles, messages
      Apply all migrations: admin, contenttypes, product, auth, sessions
    Synchronizing apps without migrations:
      Creating tables...
        Running deferred SQL...
      Installing custom SQL...
    Running migrations:
      Rendering model states... DONE
      Applying product.0004_auto_20151110_1821.../home/djangojunior2/virtualpython2/lib/python2.7/site-packages/django/db/models/fields/__init__.py:1414: RuntimeWarning: DateTimeField Product.created_at         received a naive datetime (2015-11-02 00:00:00) while time zone support is active.
      RuntimeWarning)

    /home/djangojunior2/virtualpython2/lib/python2.7/site-packages/django/db/backends/mysql/base.py:124: Warning: Data truncated for column 'modified_at' at row 1
      return self.cursor.execute(query, args)

    /home/djangojunior2/virtualpython2/lib/python2.7/site-packages/django/db/models/fields/__init__.py:1414: RuntimeWarning: DateTimeField Product.created_at received a naive datetime (2015-11-08 00:00:00) while time zone support is active.
      RuntimeWarning)

    /home/djangojunior2/virtualpython2/lib/python2.7/site-packages/django/db/models/fields/__init__.py:1414: RuntimeWarning: DateTimeField Product.created_at received a naive datetime (2015-11-09 00:00:00) while time zone support is active.
      RuntimeWarning)

    /home/djangojunior2/virtualpython2/lib/python2.7/site-packages/django/db/models/fields/__init__.py:1414: RuntimeWarning: DateTimeField Product.created_at received a naive datetime (10 00:00:00) while time zone support is active.
      RuntimeWarning)

     OK

I check Mysql db(used mysql-console), and nothing happened. Date still "2015-11-02" If I Add new data, in tables modified_at and created_at, date add to the old style ("2015-11-02").

What am I doing wrong?


Solution

  • The migrate command only handles a schema migration, not a data migration. Part of the issue is that a lot of database backends store dates and datetimes in the same field type, and it is Django that coerces them to the right types.

    So to do this you need to do a data migration as well.

    The code for your migration will look something like this, but it depends on the time to add to a time-less date:

    from django.db import models, migrations
    
    def date_to_datetime(apps, schema_editor):
        # We can't import the Person model directly as it may be a newer
        # version than this migration expects. We use the historical version.
        Product = apps.get_model("yourappname", "Product")
        for product in Product.objects.all():
            # convert a date to a date time on the product instance
            product.save()
    
    class Migration(migrations.Migration):
    
        dependencies = [
            ('yourappname', 'migration_name'),
        ]
    
        operations = [
            migrations.RunPython(date_to_datetime),
        ]