@@ -68,11 +68,59 @@ def _alter_field(
6868 new_db_params ,
6969 strict = False ,
7070 ):
71+ # Removed an index? (no strict check, as multiple indexes are possible)
72+ # Remove indexes if db_index switched to False or a unique constraint
73+ # will now be used in lieu of an index. The following lines from the
74+ # truth table show all True cases; the rest are False:
75+ #
76+ # old_field.db_index | old_field.unique | new_field.db_index | new_field.unique
77+ # ------------------------------------------------------------------------------
78+ # True | False | False | False
79+ # True | False | False | True
80+ # True | False | True | True
81+ if (
82+ old_field .db_index
83+ and not old_field .unique
84+ and (not new_field .db_index or new_field .unique )
85+ ):
86+ # Find the index for this field
87+ meta_index_names = {index .name for index in model ._meta .indexes }
88+ # Retrieve only BTREE indexes since this is what's created with
89+ # db_index=True.
90+ index_names = self ._constraint_names (
91+ model ,
92+ [old_field .column ],
93+ index = True ,
94+ type_ = Index .suffix ,
95+ exclude = meta_index_names ,
96+ )
97+ for index_name in index_names :
98+ # The only way to check if an index was created with
99+ # db_index=True or with Index(['field'], name='foo')
100+ # is to look at its name (refs #28053).
101+ self .connection .database [model ._meta .db_table ].drop_index (index_name )
71102 # Have they renamed the column?
72103 if old_field .column != new_field .column :
73104 self .connection .database [model ._meta .db_table ].update_many (
74105 {}, {"$rename" : {old_field .column : new_field .column }}
75106 )
107+ # Added an index? Add an index if db_index switched to True or a unique
108+ # constraint will no longer be used in lieu of an index. The following
109+ # lines from the truth table show all True cases; the rest are False:
110+ #
111+ # old_field.db_index | old_field.unique | new_field.db_index | new_field.unique
112+ # ------------------------------------------------------------------------------
113+ # False | False | True | False
114+ # False | True | True | False
115+ # True | True | True | False
116+ if (
117+ (not old_field .db_index or old_field .unique )
118+ and new_field .db_index
119+ and not new_field .unique
120+ ):
121+ index = Index (fields = [new_field .name ])
122+ index .name = self ._create_index_name (model ._meta .db_table , [new_field .column ])
123+ self .add_index (model , index )
76124
77125 def remove_field (self , model , field ):
78126 # Remove implicit M2M tables.
0 commit comments