Fixed #22962 -- Default values for ArrayField with migrations.
Fields normally try to force the default value to a string. As translatable strings are not valid default values for ArrayField, we can remove this behaviour which was causing issues with some migrations. Thanks to @schinckel for the report.
This commit is contained in:
parent
e5619330e2
commit
ef9f109013
|
@ -94,6 +94,14 @@ class ArrayField(Field):
|
|||
value = [self.base_field.to_python(val) for val in vals]
|
||||
return value
|
||||
|
||||
def get_default(self):
|
||||
"""Overridden from the default to prevent string-mangling."""
|
||||
if self.has_default():
|
||||
if callable(self.default):
|
||||
return self.default()
|
||||
return self.default
|
||||
return ''
|
||||
|
||||
def value_to_string(self, obj):
|
||||
values = []
|
||||
vals = self._get_val_from_obj(obj)
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
import django.contrib.postgres.fields
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='CharArrayModel',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('field', django.contrib.postgres.fields.ArrayField(models.CharField(max_length=10), size=None)),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='DateTimeArrayModel',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('field', django.contrib.postgres.fields.ArrayField(models.DateTimeField(), size=None)),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='IntegerArrayModel',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('field', django.contrib.postgres.fields.ArrayField(models.IntegerField(), size=None)),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='NestedIntegerArrayModel',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('field', django.contrib.postgres.fields.ArrayField(django.contrib.postgres.fields.ArrayField(models.IntegerField(), size=None), size=None)),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='NullableIntegerArrayModel',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('field', django.contrib.postgres.fields.ArrayField(models.IntegerField(), size=None, null=True, blank=True)),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
]
|
|
@ -0,0 +1,21 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
import django.contrib.postgres.fields
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('postgres_tests', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='integerarraymodel',
|
||||
name='field_2',
|
||||
field=django.contrib.postgres.fields.ArrayField(models.IntegerField(), default=[], size=None),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
|
@ -4,10 +4,11 @@ import unittest
|
|||
from django.contrib.postgres.fields import ArrayField
|
||||
from django.contrib.postgres.forms import SimpleArrayField, SplitArrayField
|
||||
from django.core import exceptions, serializers
|
||||
from django.core.management import call_command
|
||||
from django.db import models, IntegrityError, connection
|
||||
from django.db.migrations.writer import MigrationWriter
|
||||
from django import forms
|
||||
from django.test import TestCase
|
||||
from django.test import TestCase, override_settings
|
||||
from django.utils import timezone
|
||||
|
||||
from .models import IntegerArrayModel, NullableIntegerArrayModel, CharArrayModel, DateTimeArrayModel, NestedIntegerArrayModel
|
||||
|
@ -226,6 +227,13 @@ class TestMigrations(TestCase):
|
|||
statement, imports = MigrationWriter.serialize(field)
|
||||
self.assertEqual(statement, 'django.contrib.postgres.fields.ArrayField(models.CharField(max_length=20), size=None)')
|
||||
|
||||
@override_settings(MIGRATION_MODULES={
|
||||
"postgres_tests": "postgres_tests.array_default_migrations",
|
||||
})
|
||||
def test_adding_field_with_default(self):
|
||||
# See #22962
|
||||
call_command('migrate', 'postgres_tests', verbosity=0)
|
||||
|
||||
|
||||
@unittest.skipUnless(connection.vendor == 'postgresql', 'PostgreSQL required')
|
||||
class TestSerialization(TestCase):
|
||||
|
|
Loading…
Reference in New Issue