39

I'm using Django 1.7.1. My model looks like this:

from datetime import datetime
from django.db import models

class myModel(models.Model):
    x = models.CharField(max_length=254,null=True, blank=True,)

Everything works perfectly fine.

However, when I add the following attribute to myModel, it breaks:

    y = models.DateTimeField(default=lambda: datetime.utcnow() + timedelta(days=1), editable=False)

manage.py makemigrations gives me the following error:

ValueError: Cannot serialize function: lambda

This seems like a known bug: http://comments.gmane.org/gmane.comp.python.django.scm/125724

So how can I work around it? I need the value of y to be automatically set by default to 24 hours from the moment the model was created.

Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129
Saqib Ali
  • 11,931
  • 41
  • 133
  • 272

2 Answers2

56

The migrations documentation addresses this:

Migrations are just Python files containing the old definitions of your models - thus, to write them, Django must take the current state of your models and serialize them out into a file. While Django can serialize most things, there are some things that we just can’t serialize out into a valid Python representation....

Django can serialize the following: Any function or method reference... in module’s top-level scope

Django cannot serialize: Lambdas

So the solution is simple: instead of a lambda, define a regular function and refer to it by name.

def one_day_hence():
    return datetime.utcnow() + timezone.timedelta(days=1)

class MyModel(models.Model):
    y = models.DateTimeField(default=one_day_hence)
Community
  • 1
  • 1
Kevin Christopher Henry
  • 46,175
  • 7
  • 116
  • 102
0

I got the same error below:

ValueError: Cannot serialize function <built-in method date of datetime.datetime object at 0x0000019D077B70F0>: No module

When I set timezone.now().date to DateField() as a default value as shown below:

# "models.py"

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

class MyModel(models.Model):              # Error      
    date = models.DateField(default=timezone.now().date)

So, I set current_date without () which returns timezone.now().date() to DateField() as a default value as shown below, then the error was solved:

# "models.py"

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

def current_date(): # Here
    return timezone.now().date()

class MyModel(models.Model):        # Here      
    date = models.DateField(default=current_date)

Be careful, I can set timezone.now().date() with () to DateField() as a default value without error as shown below, but the default date becomes when the Django server starts (Unchanged):

# "models.py"

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

class MyModel(models.Model):                    # Here ↓↓      
    date = models.DateField(default=timezone.now().date())

In addition, I don't recommend to use DateField() and TimeField() because they don't work with TIME_ZONE in settings.py as I asked the question while DateTimeField() does.

Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129