@@ -66,15 +66,31 @@ def _alter_field(
6666 strict = False ,
6767 ):
6868 collection = self .connection .database [model ._meta .db_table ]
69+ # Removed an index?
70+ if self ._field_should_be_indexed (model , old_field ) and not self ._field_should_be_indexed (
71+ model , new_field
72+ ):
73+ self ._remove_field_index (model , old_field )
6974 # Have they renamed the column?
7075 if old_field .column != new_field .column :
7176 collection .update_many ({}, {"$rename" : {old_field .column : new_field .column }})
77+ # Move index to the new field, if needed.
78+ if self ._field_should_be_indexed (model , old_field ) and self ._field_should_be_indexed (
79+ model , new_field
80+ ):
81+ self ._remove_field_index (model , old_field )
82+ self ._add_field_index (model , new_field )
7283 # Replace NULL with the field default if the field and was changed from
7384 # NULL to NOT NULL.
7485 if new_field .has_default () and old_field .null and not new_field .null :
7586 column = new_field .column
7687 default = self .effective_default (new_field )
7788 collection .update_many ({column : {"$eq" : None }}, [{"$set" : {column : default }}])
89+ # Added an index?
90+ if not self ._field_should_be_indexed (model , old_field ) and self ._field_should_be_indexed (
91+ model , new_field
92+ ):
93+ self ._add_field_index (model , new_field )
7894
7995 def remove_field (self , model , field ):
8096 # Remove implicit M2M tables.
@@ -158,6 +174,28 @@ def _remove_composed_index(self, model, field_names, constraint_kwargs):
158174 collection = self .connection .database [model ._meta .db_table ]
159175 collection .drop_index (constraint_names [0 ])
160176
177+ def _remove_field_index (self , model , field ):
178+ """Remove a field's db_index=True index."""
179+ collection = self .connection .database [model ._meta .db_table ]
180+ # Find the index for this field
181+ meta_index_names = {index .name for index in model ._meta .indexes }
182+ # Retrieve only BTREE indexes since this is what's created with
183+ # db_index=True.
184+ index_names = self ._constraint_names (
185+ model ,
186+ [field .column ],
187+ index = True ,
188+ type_ = Index .suffix ,
189+ exclude = meta_index_names ,
190+ )
191+ if not index_names :
192+ raise ValueError (f"Index not found for { model ._meta .db_table } .{ field .column } ." )
193+ for index_name in index_names :
194+ # The only way to check if an index was created with
195+ # db_index=True or with Index(['field'], name='foo')
196+ # is to look at its name (refs #28053).
197+ collection .drop_index (index_name )
198+
161199 def add_constraint (self , model , constraint ):
162200 pass
163201
0 commit comments