Refs #24225 -- Added failing test case for removing a previously added field in migrations
When a related field is deleted, the related model must be updated. As unchanged models are shared in migration states, the related model must be re-rendered so that the change applies to a new copy of the related model. Thanks Henrik Heimbuerger for the report.
This commit is contained in:
parent
ad9ecc2c20
commit
58d0dd9260
|
@ -1,6 +1,6 @@
|
||||||
from django.apps.registry import Apps
|
from django.apps.registry import Apps
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.migrations.operations import RemoveField
|
from django.db.migrations.operations import DeleteModel, RemoveField
|
||||||
from django.db.migrations.state import (
|
from django.db.migrations.state import (
|
||||||
InvalidBasesError, ModelState, ProjectState,
|
InvalidBasesError, ModelState, ProjectState,
|
||||||
)
|
)
|
||||||
|
@ -366,6 +366,53 @@ class StateTests(TestCase):
|
||||||
project_state.add_model(ModelState.from_model(B))
|
project_state.add_model(ModelState.from_model(B))
|
||||||
self.assertEqual(len(project_state.apps.get_models()), 2)
|
self.assertEqual(len(project_state.apps.get_models()), 2)
|
||||||
|
|
||||||
|
def test_remove_relations(self):
|
||||||
|
"""
|
||||||
|
#24225 - Tests that relations between models are updated while
|
||||||
|
remaining the relations and references for models of an old state.
|
||||||
|
"""
|
||||||
|
class A(models.Model):
|
||||||
|
class Meta:
|
||||||
|
app_label = "something"
|
||||||
|
|
||||||
|
class B(models.Model):
|
||||||
|
to_a = models.ForeignKey(A)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
app_label = "something"
|
||||||
|
|
||||||
|
def get_model_a(state):
|
||||||
|
return [mod for mod in state.apps.get_models() if mod._meta.model_name == 'a'][0]
|
||||||
|
|
||||||
|
project_state = ProjectState()
|
||||||
|
project_state.add_model(ModelState.from_model(A))
|
||||||
|
project_state.add_model(ModelState.from_model(B))
|
||||||
|
self.assertEqual(len(get_model_a(project_state)._meta.related_objects), 1)
|
||||||
|
old_state = project_state.clone()
|
||||||
|
|
||||||
|
operation = RemoveField("b", "to_a")
|
||||||
|
operation.state_forwards("something", project_state)
|
||||||
|
# Tests that model from old_state still has the relation
|
||||||
|
model_a_old = get_model_a(old_state)
|
||||||
|
model_a_new = get_model_a(project_state)
|
||||||
|
self.assertIsNot(model_a_old, model_a_new)
|
||||||
|
self.assertEqual(len(model_a_old._meta.related_objects), 1)
|
||||||
|
self.assertEqual(len(model_a_new._meta.related_objects), 0)
|
||||||
|
|
||||||
|
# Same test for deleted model
|
||||||
|
project_state = ProjectState()
|
||||||
|
project_state.add_model(ModelState.from_model(A))
|
||||||
|
project_state.add_model(ModelState.from_model(B))
|
||||||
|
old_state = project_state.clone()
|
||||||
|
|
||||||
|
operation = DeleteModel("b")
|
||||||
|
operation.state_forwards("something", project_state)
|
||||||
|
model_a_old = get_model_a(old_state)
|
||||||
|
model_a_new = get_model_a(project_state)
|
||||||
|
self.assertIsNot(model_a_old, model_a_new)
|
||||||
|
self.assertEqual(len(model_a_old._meta.related_objects), 1)
|
||||||
|
self.assertEqual(len(model_a_new._meta.related_objects), 0)
|
||||||
|
|
||||||
def test_equality(self):
|
def test_equality(self):
|
||||||
"""
|
"""
|
||||||
Tests that == and != are implemented correctly.
|
Tests that == and != are implemented correctly.
|
||||||
|
@ -384,11 +431,13 @@ class StateTests(TestCase):
|
||||||
{},
|
{},
|
||||||
None,
|
None,
|
||||||
))
|
))
|
||||||
|
project_state.apps # Fill the apps cached property
|
||||||
other_state = project_state.clone()
|
other_state = project_state.clone()
|
||||||
self.assertEqual(project_state, project_state)
|
self.assertEqual(project_state, project_state)
|
||||||
self.assertEqual(project_state, other_state)
|
self.assertEqual(project_state, other_state)
|
||||||
self.assertEqual(project_state != project_state, False)
|
self.assertEqual(project_state != project_state, False)
|
||||||
self.assertEqual(project_state != other_state, False)
|
self.assertEqual(project_state != other_state, False)
|
||||||
|
self.assertNotEqual(project_state.apps, other_state.apps)
|
||||||
|
|
||||||
# Make a very small change (max_len 99) and see if that affects it
|
# Make a very small change (max_len 99) and see if that affects it
|
||||||
project_state = ProjectState()
|
project_state = ProjectState()
|
||||||
|
|
Loading…
Reference in New Issue