From feded19104b14bc28aaccf550265157df84593ba Mon Sep 17 00:00:00 2001
From: Andrzej Pragacz <apragacz@o2.pl>
Date: Sat, 15 Nov 2014 15:43:06 +0100
Subject: [PATCH] [1.7.x] Fixed #23794 -- Fixed migrations crash when removing
 a field that's part of index/unique_together.

Backport of 72729f844e0dd9bd01b3874171b89ab0d136a40e from master
---
 django/db/migrations/autodetector.py  | 16 +++++-----------
 docs/releases/1.7.2.txt               |  3 +++
 tests/migrations/test_autodetector.py | 16 ++++++++++++++++
 3 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/django/db/migrations/autodetector.py b/django/db/migrations/autodetector.py
index d66817a63c..d5286c7351 100644
--- a/django/db/migrations/autodetector.py
+++ b/django/db/migrations/autodetector.py
@@ -374,17 +374,11 @@ class MigrationAutodetector(object):
             )
         # Field is removed and part of an index/unique_together
         elif dependency[2] is not None and dependency[3] == "foo_together_change":
-            if operation.name.lower() == dependency[1].lower():
-                return (
-                    (
-                        isinstance(operation, operations.AlterUniqueTogether) and
-                        any(dependency[2] not in t for t in operation.unique_together)
-                    ) or
-                    (
-                        isinstance(operation, operations.AlterIndexTogether) and
-                        any(dependency[2] not in t for t in operation.index_together)
-                    )
-                )
+            return (
+                isinstance(operation, (operations.AlterUniqueTogether,
+                                       operations.AlterIndexTogether)) and
+                operation.name.lower() == dependency[1].lower()
+            )
         # Unknown dependency. Raise an error.
         else:
             raise ValueError("Can't handle dependency %r" % (dependency, ))
diff --git a/docs/releases/1.7.2.txt b/docs/releases/1.7.2.txt
index cfa68b8b3a..c9f69fe856 100644
--- a/docs/releases/1.7.2.txt
+++ b/docs/releases/1.7.2.txt
@@ -74,3 +74,6 @@ Bugfixes
 
 * Fixed a rare query error when using deeply nested subqueries
   (:ticket:`23605`).
+
+* Fixed a crash in migrations when deleting a field that is part of a
+  ``index/unique_together`` constraint (:ticket:`23794`).
diff --git a/tests/migrations/test_autodetector.py b/tests/migrations/test_autodetector.py
index 1cf0598c85..9adbf21e4d 100644
--- a/tests/migrations/test_autodetector.py
+++ b/tests/migrations/test_autodetector.py
@@ -875,6 +875,22 @@ class AutodetectorTests(TestCase):
         self.assertOperationAttributes(changes, "otherapp", 0, 0, name="book", unique_together=set())
         self.assertOperationAttributes(changes, "otherapp", 0, 1, name="book", index_together=set())
 
+    def test_foo_together_remove_fk(self):
+        """Tests unique_together and field removal detection & ordering"""
+        # Make state
+        before = self.make_project_state([self.author_empty, self.book_foo_together])
+        after = self.make_project_state([self.author_empty, self.book_with_no_author])
+        autodetector = MigrationAutodetector(before, after)
+        changes = autodetector._detect_changes()
+        # Right number/type of migrations?
+        self.assertNumberMigrations(changes, "otherapp", 1)
+        self.assertOperationTypes(changes, "otherapp", 0, [
+            "AlterUniqueTogether", "AlterIndexTogether", "RemoveField"
+        ])
+        self.assertOperationAttributes(changes, "otherapp", 0, 0, name="book", unique_together=set())
+        self.assertOperationAttributes(changes, "otherapp", 0, 1, name="book", index_together=set())
+        self.assertOperationAttributes(changes, "otherapp", 0, 2, model_name="book", name="author")
+
     def test_foo_together_no_changes(self):
         """
         Tests that index/unique_together doesn't generate a migration if no