Opened 6 years ago
Last modified 6 years ago
#29852 closed Bug
SimpleLazyObject Causing Migrations to be created over and over — at Initial Version
Reported by: | Javier Buzzi | Owned by: | nobody |
---|---|---|---|
Component: | Migrations | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Accepted | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | yes |
Easy pickings: | no | UI/UX: | no |
Description
Reference: https://code.djangoproject.com/ticket/29772
from django.db import models from django.utils.functional import SimpleLazyObject from django.core.validators import MinValueValidator import datetime # Create your models here. class Thing(models.Model): day = models.DateTimeField(validators=[MinValueValidator(SimpleLazyObject(datetime.datetime.now))])
This works great right up until you try running migrations:
- First time it creates a
- Create model Thing
- Then you run the same command again and again, and will always generate a new migration
- Alter field day on thing
class Migration(migrations.Migration): dependencies = [ ('app', '0005_auto_20181015_2203'), ] operations = [ migrations.AlterField( model_name='thing', name='day', field=models.DateTimeField(validators=[django.core.validators.MinValueValidator(datetime.datetime(2018, 10, 15, 22, 3, 41, 390769))]), ), ]
The issue being that the now()
is being evaluated and thus is always different.
I got it 50% working with this diff:
diff --git a/django/db/migrations/serializer.py b/django/db/migrations/serializer.py index 911cf0f..ef2ad43 100644 --- a/django/db/migrations/serializer.py +++ b/django/db/migrations/serializer.py @@ -12,7 +12,7 @@ import uuid from django.db import models from django.db.migrations.operations.base import Operation from django.db.migrations.utils import COMPILED_REGEX_TYPE, RegexObject -from django.utils.functional import LazyObject, Promise +from django.utils.functional import LazyObject, Promise, SimpleLazyObject from django.utils.timezone import utc from django.utils.version import get_docs_version @@ -273,6 +273,8 @@ def serializer_factory(value): from django.db.migrations.writer import SettingsReference if isinstance(value, Promise): value = str(value) + elif isinstance(value, SimpleLazyObject): + value = value._setupfunc elif isinstance(value, LazyObject): # The unwrapped value is returned as the first item of the arguments # tuple.
Turns the migrations into:
class Migration(migrations.Migration): dependencies = [ ('app', '0004_auto_20181015_2203'), ] operations = [ migrations.AlterField( model_name='thing', name='day', field=models.DateTimeField(validators=[django.core.validators.MinValueValidator(datetime.datetime.now)]), ), ]
While it's a great improvement, it still generates a new one every time. I'm a little over my head with this one, this code is very dense. I could keep looking at it tomorrow, but i need someone to point me in the right direction + where in the world do i put the tests for this thing?? Thanks.