[PATCH 3/3] migrations: Add the default value of Patch.state
Damien Lespiau
damien.lespiau at intel.com
Fri Aug 21 02:13:49 AEST 2015
Now that we have migration 0002 populating the db with the intial list
of states, we can add the default Patch.state value (which depends on
being able to query the state with ordering=0).
Of course, it's not that simple and I was hitting an exception
Applying patchwork.0003_patch_state_default_value...Traceback (most recent call last):
[...]
File "django/db/migrations/executor.py", line 148, in apply_migration
state = migration.apply(state, schema_editor)
File "django/db/migrations/migration.py", line 115, in apply
operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
File "django/db/migrations/operations/fields.py", line 201, in database_forwards
schema_editor.alter_field(from_model, from_field, to_field)
File "django/db/backends/base/schema.py", line 484, in alter_field
old_db_params, new_db_params, strict)
File "django/db/backends/base/schema.py", line 567, in _alter_field
new_default = self.effective_default(new_field)
File "django/db/backends/base/schema.py", line 211, in effective_default
default = field.get_db_prep_save(default, self.connection)
File "django/db/models/fields/related.py", line 1956, in get_db_prep_save
return self.related_field.get_db_prep_save(value, connection=connection)
File "django/db/models/fields/__init__.py", line 710, in get_db_prep_save
prepared=False)
File "django/db/models/fields/__init__.py", line 977, in get_db_prep_value
value = self.get_prep_value(value)
File "django/db/models/fields/__init__.py", line 985, in get_prep_value
return int(value)
TypeError: int() argument must be a string or a number, not 'State'
Django was trying to make an int out of the State instance returned by
get_default_initial_patch_state(). Turns out I wasn't the first one to
hit that:
"Migration crash on ForeignKey with a callable default that returns a
model instance"
Source: https://code.djangoproject.com/ticket/25129
And the solution decided by the django developers was to restrict what
callable defaults can return with ForeignKeys:
"For fields like ForeignKey that map to model instances, defaults
should be the value of the field they reference (pk unless to_field is
set) instead of model instances."
Source: https://docs.djangoproject.com/en/dev/ref/models/fields/#default
v2: Don't change get_default_initial_patch_state() as it's used outside
of models.py
Signed-off-by: Damien Lespiau <damien.lespiau at intel.com>
---
.../migrations/0003_patch_state_default_value.py | 20 ++++++++++++++++++++
patchwork/models.py | 5 ++++-
2 files changed, 24 insertions(+), 1 deletion(-)
create mode 100644 patchwork/migrations/0003_patch_state_default_value.py
diff --git a/patchwork/migrations/0003_patch_state_default_value.py b/patchwork/migrations/0003_patch_state_default_value.py
new file mode 100644
index 0000000..3324406
--- /dev/null
+++ b/patchwork/migrations/0003_patch_state_default_value.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+import patchwork.models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('patchwork', '0002_load_initial_data'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='patch',
+ name='state',
+ field=models.ForeignKey(default=patchwork.models.get_default_initial_patch_state_pk, to='patchwork.State'),
+ ),
+ ]
diff --git a/patchwork/models.py b/patchwork/models.py
index c2b8a9c..4a1a432 100644
--- a/patchwork/models.py
+++ b/patchwork/models.py
@@ -205,6 +205,9 @@ class PatchTag(models.Model):
def get_default_initial_patch_state():
return State.objects.get(ordering=0)
+def get_default_initial_patch_state_pk():
+ return get_default_initial_patch_state().pk
+
class PatchQuerySet(models.query.QuerySet):
def with_tag_counts(self, project):
@@ -243,7 +246,7 @@ class Patch(models.Model):
date = models.DateTimeField(default=datetime.datetime.now)
submitter = models.ForeignKey(Person)
delegate = models.ForeignKey(User, blank = True, null = True)
- state = models.ForeignKey(State, default=get_default_initial_patch_state)
+ state = models.ForeignKey(State, default=get_default_initial_patch_state_pk)
archived = models.BooleanField(default = False)
headers = models.TextField(blank = True)
content = models.TextField(null = True, blank = True)
--
2.1.0
More information about the Patchwork
mailing list