|
@@ -13,9 +13,8 @@ from django.db.migrations.graph import MigrationGraph
|
|
|
from django.db.migrations.loader import MigrationLoader
|
|
|
from django.db.migrations.questioner import MigrationQuestioner
|
|
|
from django.db.migrations.state import ModelState, ProjectState
|
|
|
-from django.test import SimpleTestCase, TestCase, ignore_warnings, override_settings
|
|
|
+from django.test import SimpleTestCase, TestCase, override_settings
|
|
|
from django.test.utils import isolate_lru_cache
|
|
|
-from django.utils.deprecation import RemovedInDjango51Warning
|
|
|
|
|
|
from .models import FoodManager, FoodQuerySet
|
|
|
|
|
@@ -4872,592 +4871,6 @@ class AutodetectorTests(BaseAutodetectorTests):
|
|
|
self.assertOperationAttributes(changes, "testapp", 0, 0, name="Book")
|
|
|
|
|
|
|
|
|
-@ignore_warnings(category=RemovedInDjango51Warning)
|
|
|
-class AutodetectorIndexTogetherTests(BaseAutodetectorTests):
|
|
|
- book_index_together = ModelState(
|
|
|
- "otherapp",
|
|
|
- "Book",
|
|
|
- [
|
|
|
- ("id", models.AutoField(primary_key=True)),
|
|
|
- ("author", models.ForeignKey("testapp.Author", models.CASCADE)),
|
|
|
- ("title", models.CharField(max_length=200)),
|
|
|
- ],
|
|
|
- {
|
|
|
- "index_together": {("author", "title")},
|
|
|
- },
|
|
|
- )
|
|
|
- book_index_together_2 = ModelState(
|
|
|
- "otherapp",
|
|
|
- "Book",
|
|
|
- [
|
|
|
- ("id", models.AutoField(primary_key=True)),
|
|
|
- ("author", models.ForeignKey("testapp.Author", models.CASCADE)),
|
|
|
- ("title", models.CharField(max_length=200)),
|
|
|
- ],
|
|
|
- {
|
|
|
- "index_together": {("title", "author")},
|
|
|
- },
|
|
|
- )
|
|
|
- book_index_together_3 = ModelState(
|
|
|
- "otherapp",
|
|
|
- "Book",
|
|
|
- [
|
|
|
- ("id", models.AutoField(primary_key=True)),
|
|
|
- ("newfield", models.IntegerField()),
|
|
|
- ("author", models.ForeignKey("testapp.Author", models.CASCADE)),
|
|
|
- ("title", models.CharField(max_length=200)),
|
|
|
- ],
|
|
|
- {
|
|
|
- "index_together": {("title", "newfield")},
|
|
|
- },
|
|
|
- )
|
|
|
- book_index_together_4 = ModelState(
|
|
|
- "otherapp",
|
|
|
- "Book",
|
|
|
- [
|
|
|
- ("id", models.AutoField(primary_key=True)),
|
|
|
- ("newfield2", models.IntegerField()),
|
|
|
- ("author", models.ForeignKey("testapp.Author", models.CASCADE)),
|
|
|
- ("title", models.CharField(max_length=200)),
|
|
|
- ],
|
|
|
- {
|
|
|
- "index_together": {("title", "newfield2")},
|
|
|
- },
|
|
|
- )
|
|
|
-
|
|
|
- def test_empty_index_together(self):
|
|
|
- """Empty index_together shouldn't generate a migration."""
|
|
|
- # Explicitly testing for not specified, since this is the case after
|
|
|
- # a CreateModel operation w/o any definition on the original model
|
|
|
- model_state_not_specified = ModelState(
|
|
|
- "a", "model", [("id", models.AutoField(primary_key=True))]
|
|
|
- )
|
|
|
- # Explicitly testing for None, since this was the issue in #23452 after
|
|
|
- # an AlterIndexTogether operation with e.g. () as value
|
|
|
- model_state_none = ModelState(
|
|
|
- "a",
|
|
|
- "model",
|
|
|
- [("id", models.AutoField(primary_key=True))],
|
|
|
- {
|
|
|
- "index_together": None,
|
|
|
- },
|
|
|
- )
|
|
|
- # Explicitly testing for the empty set, since we now always have sets.
|
|
|
- # During removal (('col1', 'col2'),) --> () this becomes set([])
|
|
|
- model_state_empty = ModelState(
|
|
|
- "a",
|
|
|
- "model",
|
|
|
- [("id", models.AutoField(primary_key=True))],
|
|
|
- {
|
|
|
- "index_together": set(),
|
|
|
- },
|
|
|
- )
|
|
|
-
|
|
|
- def test(from_state, to_state, msg):
|
|
|
- changes = self.get_changes([from_state], [to_state])
|
|
|
- if changes:
|
|
|
- ops = ", ".join(
|
|
|
- o.__class__.__name__ for o in changes["a"][0].operations
|
|
|
- )
|
|
|
- self.fail("Created operation(s) %s from %s" % (ops, msg))
|
|
|
-
|
|
|
- tests = (
|
|
|
- (
|
|
|
- model_state_not_specified,
|
|
|
- model_state_not_specified,
|
|
|
- '"not specified" to "not specified"',
|
|
|
- ),
|
|
|
- (model_state_not_specified, model_state_none, '"not specified" to "None"'),
|
|
|
- (
|
|
|
- model_state_not_specified,
|
|
|
- model_state_empty,
|
|
|
- '"not specified" to "empty"',
|
|
|
- ),
|
|
|
- (model_state_none, model_state_not_specified, '"None" to "not specified"'),
|
|
|
- (model_state_none, model_state_none, '"None" to "None"'),
|
|
|
- (model_state_none, model_state_empty, '"None" to "empty"'),
|
|
|
- (
|
|
|
- model_state_empty,
|
|
|
- model_state_not_specified,
|
|
|
- '"empty" to "not specified"',
|
|
|
- ),
|
|
|
- (model_state_empty, model_state_none, '"empty" to "None"'),
|
|
|
- (model_state_empty, model_state_empty, '"empty" to "empty"'),
|
|
|
- )
|
|
|
-
|
|
|
- for t in tests:
|
|
|
- test(*t)
|
|
|
-
|
|
|
- def test_rename_index_together_to_index(self):
|
|
|
- changes = self.get_changes(
|
|
|
- [AutodetectorTests.author_empty, self.book_index_together],
|
|
|
- [AutodetectorTests.author_empty, AutodetectorTests.book_indexes],
|
|
|
- )
|
|
|
- self.assertNumberMigrations(changes, "otherapp", 1)
|
|
|
- self.assertOperationTypes(changes, "otherapp", 0, ["RenameIndex"])
|
|
|
- self.assertOperationAttributes(
|
|
|
- changes,
|
|
|
- "otherapp",
|
|
|
- 0,
|
|
|
- 0,
|
|
|
- model_name="book",
|
|
|
- new_name="book_title_author_idx",
|
|
|
- old_fields=("author", "title"),
|
|
|
- )
|
|
|
-
|
|
|
- def test_rename_index_together_to_index_extra_options(self):
|
|
|
- # Indexes with extra options don't match indexes in index_together.
|
|
|
- book_partial_index = ModelState(
|
|
|
- "otherapp",
|
|
|
- "Book",
|
|
|
- [
|
|
|
- ("id", models.AutoField(primary_key=True)),
|
|
|
- ("author", models.ForeignKey("testapp.Author", models.CASCADE)),
|
|
|
- ("title", models.CharField(max_length=200)),
|
|
|
- ],
|
|
|
- {
|
|
|
- "indexes": [
|
|
|
- models.Index(
|
|
|
- fields=["author", "title"],
|
|
|
- condition=models.Q(title__startswith="The"),
|
|
|
- name="book_title_author_idx",
|
|
|
- )
|
|
|
- ],
|
|
|
- },
|
|
|
- )
|
|
|
- changes = self.get_changes(
|
|
|
- [AutodetectorTests.author_empty, self.book_index_together],
|
|
|
- [AutodetectorTests.author_empty, book_partial_index],
|
|
|
- )
|
|
|
- self.assertNumberMigrations(changes, "otherapp", 1)
|
|
|
- self.assertOperationTypes(
|
|
|
- changes,
|
|
|
- "otherapp",
|
|
|
- 0,
|
|
|
- ["AlterIndexTogether", "AddIndex"],
|
|
|
- )
|
|
|
-
|
|
|
- def test_rename_index_together_to_index_order_fields(self):
|
|
|
- # Indexes with reordered fields don't match indexes in index_together.
|
|
|
- changes = self.get_changes(
|
|
|
- [AutodetectorTests.author_empty, self.book_index_together],
|
|
|
- [AutodetectorTests.author_empty, AutodetectorTests.book_unordered_indexes],
|
|
|
- )
|
|
|
- self.assertNumberMigrations(changes, "otherapp", 1)
|
|
|
- self.assertOperationTypes(
|
|
|
- changes,
|
|
|
- "otherapp",
|
|
|
- 0,
|
|
|
- ["AlterIndexTogether", "AddIndex"],
|
|
|
- )
|
|
|
-
|
|
|
- def test_add_index_together(self):
|
|
|
- changes = self.get_changes(
|
|
|
- [AutodetectorTests.author_empty, AutodetectorTests.book],
|
|
|
- [AutodetectorTests.author_empty, self.book_index_together],
|
|
|
- )
|
|
|
- self.assertNumberMigrations(changes, "otherapp", 1)
|
|
|
- self.assertOperationTypes(changes, "otherapp", 0, ["AlterIndexTogether"])
|
|
|
- self.assertOperationAttributes(
|
|
|
- changes, "otherapp", 0, 0, name="book", index_together={("author", "title")}
|
|
|
- )
|
|
|
-
|
|
|
- def test_remove_index_together(self):
|
|
|
- changes = self.get_changes(
|
|
|
- [AutodetectorTests.author_empty, self.book_index_together],
|
|
|
- [AutodetectorTests.author_empty, AutodetectorTests.book],
|
|
|
- )
|
|
|
- self.assertNumberMigrations(changes, "otherapp", 1)
|
|
|
- self.assertOperationTypes(changes, "otherapp", 0, ["AlterIndexTogether"])
|
|
|
- self.assertOperationAttributes(
|
|
|
- changes, "otherapp", 0, 0, name="book", index_together=set()
|
|
|
- )
|
|
|
-
|
|
|
- def test_index_together_remove_fk(self):
|
|
|
- changes = self.get_changes(
|
|
|
- [AutodetectorTests.author_empty, self.book_index_together],
|
|
|
- [AutodetectorTests.author_empty, AutodetectorTests.book_with_no_author],
|
|
|
- )
|
|
|
- self.assertNumberMigrations(changes, "otherapp", 1)
|
|
|
- self.assertOperationTypes(
|
|
|
- changes,
|
|
|
- "otherapp",
|
|
|
- 0,
|
|
|
- ["AlterIndexTogether", "RemoveField"],
|
|
|
- )
|
|
|
- self.assertOperationAttributes(
|
|
|
- changes, "otherapp", 0, 0, name="book", index_together=set()
|
|
|
- )
|
|
|
- self.assertOperationAttributes(
|
|
|
- changes, "otherapp", 0, 1, model_name="book", name="author"
|
|
|
- )
|
|
|
-
|
|
|
- def test_index_together_no_changes(self):
|
|
|
- """
|
|
|
- index_together doesn't generate a migration if no changes have been
|
|
|
- made.
|
|
|
- """
|
|
|
- changes = self.get_changes(
|
|
|
- [AutodetectorTests.author_empty, self.book_index_together],
|
|
|
- [AutodetectorTests.author_empty, self.book_index_together],
|
|
|
- )
|
|
|
- self.assertEqual(len(changes), 0)
|
|
|
-
|
|
|
- def test_index_together_ordering(self):
|
|
|
- """index_together triggers on ordering changes."""
|
|
|
- changes = self.get_changes(
|
|
|
- [AutodetectorTests.author_empty, self.book_index_together],
|
|
|
- [AutodetectorTests.author_empty, self.book_index_together_2],
|
|
|
- )
|
|
|
- self.assertNumberMigrations(changes, "otherapp", 1)
|
|
|
- self.assertOperationTypes(
|
|
|
- changes,
|
|
|
- "otherapp",
|
|
|
- 0,
|
|
|
- ["AlterIndexTogether"],
|
|
|
- )
|
|
|
- self.assertOperationAttributes(
|
|
|
- changes,
|
|
|
- "otherapp",
|
|
|
- 0,
|
|
|
- 0,
|
|
|
- name="book",
|
|
|
- index_together={("title", "author")},
|
|
|
- )
|
|
|
-
|
|
|
- def test_add_field_and_index_together(self):
|
|
|
- """
|
|
|
- Added fields will be created before using them in index_together.
|
|
|
- """
|
|
|
- changes = self.get_changes(
|
|
|
- [AutodetectorTests.author_empty, AutodetectorTests.book],
|
|
|
- [AutodetectorTests.author_empty, self.book_index_together_3],
|
|
|
- )
|
|
|
- self.assertNumberMigrations(changes, "otherapp", 1)
|
|
|
- self.assertOperationTypes(
|
|
|
- changes,
|
|
|
- "otherapp",
|
|
|
- 0,
|
|
|
- ["AddField", "AlterIndexTogether"],
|
|
|
- )
|
|
|
- self.assertOperationAttributes(
|
|
|
- changes,
|
|
|
- "otherapp",
|
|
|
- 0,
|
|
|
- 1,
|
|
|
- name="book",
|
|
|
- index_together={("title", "newfield")},
|
|
|
- )
|
|
|
-
|
|
|
- def test_create_model_and_index_together(self):
|
|
|
- author = ModelState(
|
|
|
- "otherapp",
|
|
|
- "Author",
|
|
|
- [
|
|
|
- ("id", models.AutoField(primary_key=True)),
|
|
|
- ("name", models.CharField(max_length=200)),
|
|
|
- ],
|
|
|
- )
|
|
|
- book_with_author = ModelState(
|
|
|
- "otherapp",
|
|
|
- "Book",
|
|
|
- [
|
|
|
- ("id", models.AutoField(primary_key=True)),
|
|
|
- ("author", models.ForeignKey("otherapp.Author", models.CASCADE)),
|
|
|
- ("title", models.CharField(max_length=200)),
|
|
|
- ],
|
|
|
- {
|
|
|
- "index_together": {("title", "author")},
|
|
|
- },
|
|
|
- )
|
|
|
- changes = self.get_changes(
|
|
|
- [AutodetectorTests.book_with_no_author], [author, book_with_author]
|
|
|
- )
|
|
|
- self.assertEqual(len(changes["otherapp"]), 1)
|
|
|
- migration = changes["otherapp"][0]
|
|
|
- self.assertEqual(len(migration.operations), 3)
|
|
|
- self.assertOperationTypes(
|
|
|
- changes,
|
|
|
- "otherapp",
|
|
|
- 0,
|
|
|
- ["CreateModel", "AddField", "AlterIndexTogether"],
|
|
|
- )
|
|
|
-
|
|
|
- def test_remove_field_and_index_together(self):
|
|
|
- """
|
|
|
- Removed fields will be removed after updating index_together.
|
|
|
- """
|
|
|
- changes = self.get_changes(
|
|
|
- [AutodetectorTests.author_empty, self.book_index_together_3],
|
|
|
- [AutodetectorTests.author_empty, self.book_index_together],
|
|
|
- )
|
|
|
- self.assertNumberMigrations(changes, "otherapp", 1)
|
|
|
- self.assertOperationTypes(
|
|
|
- changes,
|
|
|
- "otherapp",
|
|
|
- 0,
|
|
|
- ["AlterIndexTogether", "RemoveField"],
|
|
|
- )
|
|
|
- self.assertOperationAttributes(
|
|
|
- changes,
|
|
|
- "otherapp",
|
|
|
- 0,
|
|
|
- 0,
|
|
|
- name="book",
|
|
|
- index_together={("author", "title")},
|
|
|
- )
|
|
|
- self.assertOperationAttributes(
|
|
|
- changes,
|
|
|
- "otherapp",
|
|
|
- 0,
|
|
|
- 1,
|
|
|
- model_name="book",
|
|
|
- name="newfield",
|
|
|
- )
|
|
|
-
|
|
|
- def test_alter_field_and_index_together(self):
|
|
|
- """Fields are altered after deleting some index_together."""
|
|
|
- initial_author = ModelState(
|
|
|
- "testapp",
|
|
|
- "Author",
|
|
|
- [
|
|
|
- ("id", models.AutoField(primary_key=True)),
|
|
|
- ("name", models.CharField(max_length=200)),
|
|
|
- ("age", models.IntegerField(db_index=True)),
|
|
|
- ],
|
|
|
- {
|
|
|
- "index_together": {("name",)},
|
|
|
- },
|
|
|
- )
|
|
|
- author_reversed_constraints = ModelState(
|
|
|
- "testapp",
|
|
|
- "Author",
|
|
|
- [
|
|
|
- ("id", models.AutoField(primary_key=True)),
|
|
|
- ("name", models.CharField(max_length=200, unique=True)),
|
|
|
- ("age", models.IntegerField()),
|
|
|
- ],
|
|
|
- {
|
|
|
- "index_together": {("age",)},
|
|
|
- },
|
|
|
- )
|
|
|
- changes = self.get_changes([initial_author], [author_reversed_constraints])
|
|
|
-
|
|
|
- self.assertNumberMigrations(changes, "testapp", 1)
|
|
|
- self.assertOperationTypes(
|
|
|
- changes,
|
|
|
- "testapp",
|
|
|
- 0,
|
|
|
- [
|
|
|
- "AlterIndexTogether",
|
|
|
- "AlterField",
|
|
|
- "AlterField",
|
|
|
- "AlterIndexTogether",
|
|
|
- ],
|
|
|
- )
|
|
|
- self.assertOperationAttributes(
|
|
|
- changes,
|
|
|
- "testapp",
|
|
|
- 0,
|
|
|
- 0,
|
|
|
- name="author",
|
|
|
- index_together=set(),
|
|
|
- )
|
|
|
- self.assertOperationAttributes(
|
|
|
- changes,
|
|
|
- "testapp",
|
|
|
- 0,
|
|
|
- 1,
|
|
|
- model_name="author",
|
|
|
- name="age",
|
|
|
- )
|
|
|
- self.assertOperationAttributes(
|
|
|
- changes,
|
|
|
- "testapp",
|
|
|
- 0,
|
|
|
- 2,
|
|
|
- model_name="author",
|
|
|
- name="name",
|
|
|
- )
|
|
|
- self.assertOperationAttributes(
|
|
|
- changes,
|
|
|
- "testapp",
|
|
|
- 0,
|
|
|
- 3,
|
|
|
- name="author",
|
|
|
- index_together={("age",)},
|
|
|
- )
|
|
|
-
|
|
|
- def test_partly_alter_index_together_increase(self):
|
|
|
- initial_author = ModelState(
|
|
|
- "testapp",
|
|
|
- "Author",
|
|
|
- [
|
|
|
- ("id", models.AutoField(primary_key=True)),
|
|
|
- ("name", models.CharField(max_length=200)),
|
|
|
- ("age", models.IntegerField()),
|
|
|
- ],
|
|
|
- {
|
|
|
- "index_together": {("name",)},
|
|
|
- },
|
|
|
- )
|
|
|
- author_new_constraints = ModelState(
|
|
|
- "testapp",
|
|
|
- "Author",
|
|
|
- [
|
|
|
- ("id", models.AutoField(primary_key=True)),
|
|
|
- ("name", models.CharField(max_length=200)),
|
|
|
- ("age", models.IntegerField()),
|
|
|
- ],
|
|
|
- {
|
|
|
- "index_together": {("name",), ("age",)},
|
|
|
- },
|
|
|
- )
|
|
|
- changes = self.get_changes([initial_author], [author_new_constraints])
|
|
|
-
|
|
|
- self.assertNumberMigrations(changes, "testapp", 1)
|
|
|
- self.assertOperationTypes(
|
|
|
- changes,
|
|
|
- "testapp",
|
|
|
- 0,
|
|
|
- ["AlterIndexTogether"],
|
|
|
- )
|
|
|
- self.assertOperationAttributes(
|
|
|
- changes,
|
|
|
- "testapp",
|
|
|
- 0,
|
|
|
- 0,
|
|
|
- name="author",
|
|
|
- index_together={("name",), ("age",)},
|
|
|
- )
|
|
|
-
|
|
|
- def test_partly_alter_index_together_decrease(self):
|
|
|
- initial_author = ModelState(
|
|
|
- "testapp",
|
|
|
- "Author",
|
|
|
- [
|
|
|
- ("id", models.AutoField(primary_key=True)),
|
|
|
- ("name", models.CharField(max_length=200)),
|
|
|
- ("age", models.IntegerField()),
|
|
|
- ],
|
|
|
- {
|
|
|
- "index_together": {("name",), ("age",)},
|
|
|
- },
|
|
|
- )
|
|
|
- author_new_constraints = ModelState(
|
|
|
- "testapp",
|
|
|
- "Author",
|
|
|
- [
|
|
|
- ("id", models.AutoField(primary_key=True)),
|
|
|
- ("name", models.CharField(max_length=200)),
|
|
|
- ("age", models.IntegerField()),
|
|
|
- ],
|
|
|
- {
|
|
|
- "index_together": {("age",)},
|
|
|
- },
|
|
|
- )
|
|
|
- changes = self.get_changes([initial_author], [author_new_constraints])
|
|
|
-
|
|
|
- self.assertNumberMigrations(changes, "testapp", 1)
|
|
|
- self.assertOperationTypes(
|
|
|
- changes,
|
|
|
- "testapp",
|
|
|
- 0,
|
|
|
- ["AlterIndexTogether"],
|
|
|
- )
|
|
|
- self.assertOperationAttributes(
|
|
|
- changes,
|
|
|
- "testapp",
|
|
|
- 0,
|
|
|
- 0,
|
|
|
- name="author",
|
|
|
- index_together={("age",)},
|
|
|
- )
|
|
|
-
|
|
|
- def test_rename_field_and_index_together(self):
|
|
|
- """Fields are renamed before updating index_together."""
|
|
|
- changes = self.get_changes(
|
|
|
- [AutodetectorTests.author_empty, self.book_index_together_3],
|
|
|
- [AutodetectorTests.author_empty, self.book_index_together_4],
|
|
|
- MigrationQuestioner({"ask_rename": True}),
|
|
|
- )
|
|
|
- self.assertNumberMigrations(changes, "otherapp", 1)
|
|
|
- self.assertOperationTypes(
|
|
|
- changes,
|
|
|
- "otherapp",
|
|
|
- 0,
|
|
|
- ["RenameField", "AlterIndexTogether"],
|
|
|
- )
|
|
|
- self.assertOperationAttributes(
|
|
|
- changes,
|
|
|
- "otherapp",
|
|
|
- 0,
|
|
|
- 1,
|
|
|
- name="book",
|
|
|
- index_together={("title", "newfield2")},
|
|
|
- )
|
|
|
-
|
|
|
- def test_add_model_order_with_respect_to_index_together(self):
|
|
|
- changes = self.get_changes(
|
|
|
- [],
|
|
|
- [
|
|
|
- AutodetectorTests.book,
|
|
|
- ModelState(
|
|
|
- "testapp",
|
|
|
- "Author",
|
|
|
- [
|
|
|
- ("id", models.AutoField(primary_key=True)),
|
|
|
- ("name", models.CharField(max_length=200)),
|
|
|
- ("book", models.ForeignKey("otherapp.Book", models.CASCADE)),
|
|
|
- ],
|
|
|
- options={
|
|
|
- "order_with_respect_to": "book",
|
|
|
- "index_together": {("name", "_order")},
|
|
|
- },
|
|
|
- ),
|
|
|
- ],
|
|
|
- )
|
|
|
- self.assertNumberMigrations(changes, "testapp", 1)
|
|
|
- self.assertOperationTypes(changes, "testapp", 0, ["CreateModel"])
|
|
|
- self.assertOperationAttributes(
|
|
|
- changes,
|
|
|
- "testapp",
|
|
|
- 0,
|
|
|
- 0,
|
|
|
- name="Author",
|
|
|
- options={
|
|
|
- "order_with_respect_to": "book",
|
|
|
- "index_together": {("name", "_order")},
|
|
|
- },
|
|
|
- )
|
|
|
-
|
|
|
- def test_set_alter_order_with_respect_to_index_together(self):
|
|
|
- after = ModelState(
|
|
|
- "testapp",
|
|
|
- "Author",
|
|
|
- [
|
|
|
- ("id", models.AutoField(primary_key=True)),
|
|
|
- ("name", models.CharField(max_length=200)),
|
|
|
- ("book", models.ForeignKey("otherapp.Book", models.CASCADE)),
|
|
|
- ],
|
|
|
- options={
|
|
|
- "order_with_respect_to": "book",
|
|
|
- "index_together": {("name", "_order")},
|
|
|
- },
|
|
|
- )
|
|
|
- changes = self.get_changes(
|
|
|
- [AutodetectorTests.book, AutodetectorTests.author_with_book],
|
|
|
- [AutodetectorTests.book, after],
|
|
|
- )
|
|
|
- self.assertNumberMigrations(changes, "testapp", 1)
|
|
|
- self.assertOperationTypes(
|
|
|
- changes,
|
|
|
- "testapp",
|
|
|
- 0,
|
|
|
- ["AlterOrderWithRespectTo", "AlterIndexTogether"],
|
|
|
- )
|
|
|
-
|
|
|
-
|
|
|
class MigrationSuggestNameTests(SimpleTestCase):
|
|
|
def test_no_operations(self):
|
|
|
class Migration(migrations.Migration):
|