Skip to content

Commit

Permalink
Fixed #22435 -- Prevented adding a ManyToManyField from prompting for…
Browse files Browse the repository at this point in the history
… a default.

Thanks andrewsg for the report.
  • Loading branch information
timgraham committed May 3, 2014
1 parent 142c272 commit 3818d96
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 1 deletion.
3 changes: 2 additions & 1 deletion django/db/migrations/autodetector.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import re
import datetime

from django.db import models
from django.db.migrations import operations
from django.db.migrations.migration import Migration
from django.db.migrations.questioner import MigrationQuestioner
Expand Down Expand Up @@ -299,7 +300,7 @@ def _rel_agnostic_fields_def(fields):
if found_rename:
continue
# You can't just add NOT NULL fields with no default
if not field.null and not field.has_default():
if not field.null and not field.has_default() and not isinstance(field, models.ManyToManyField):
field = field.clone()
field.default = self.questioner.ask_not_null_addition(field_name, model_name)
self.add_to_migration(
Expand Down
26 changes: 26 additions & 0 deletions tests/migrations/test_autodetector.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ class AutodetectorTests(TestCase):
author_proxy_notproxy = ModelState("testapp", "AuthorProxy", [], {}, ("testapp.author", ))
author_unmanaged = ModelState("testapp", "AuthorUnmanaged", [], {"managed": False}, ("testapp.author", ))
author_unmanaged_managed = ModelState("testapp", "AuthorUnmanaged", [], {}, ("testapp.author", ))
author_with_m2m = ModelState("testapp", "Author", [
("id", models.AutoField(primary_key=True)),
("publishers", models.ManyToManyField("testapp.Publisher")),
])
publisher = ModelState("testapp", "Publisher", [("id", models.AutoField(primary_key=True)), ("name", models.CharField(max_length=100))])
publisher_with_author = ModelState("testapp", "Publisher", [("id", models.AutoField(primary_key=True)), ("author", models.ForeignKey("testapp.Author")), ("name", models.CharField(max_length=100))])
publisher_with_book = ModelState("testapp", "Publisher", [("id", models.AutoField(primary_key=True)), ("author", models.ForeignKey("otherapp.Book")), ("name", models.CharField(max_length=100))])
Expand Down Expand Up @@ -619,6 +623,28 @@ def test_foreign_key_removed_before_target_model(self):
self.assertEqual(action.__class__.__name__, "DeleteModel")
self.assertEqual(action.name, "Publisher")

def test_add_many_to_many(self):
"""
Adding a ManyToManyField should not prompt for a default (#22435).
"""
class CustomQuestioner(MigrationQuestioner):
def ask_not_null_addition(self, field_name, model_name):
raise Exception("Should not have prompted for not null addition")

before = self.make_project_state([self.author_empty, self.publisher])
# Add ManyToManyField to author model
after = self.make_project_state([self.author_with_m2m, self.publisher])
autodetector = MigrationAutodetector(before, after, CustomQuestioner())
changes = autodetector._detect_changes()
# Right number of migrations?
self.assertEqual(len(changes['testapp']), 1)
migration = changes['testapp'][0]
# Right actions in right order?
self.assertEqual(len(migration.operations), 1)
action = migration.operations[0]
self.assertEqual(action.__class__.__name__, "AddField")
self.assertEqual(action.name, "publishers")

def test_many_to_many_removed_before_through_model(self):
"""
Removing a ManyToManyField and the "through" model in the same change must remove
Expand Down

0 comments on commit 3818d96

Please sign in to comment.