Remove a field from a model. Usually involves deleting a column, but for M2Ms may involve deleting a table.
(self, model, field)
| 816 | self.connection.close() |
| 817 | |
| 818 | def remove_field(self, model, field): |
| 819 | """ |
| 820 | Remove a field from a model. Usually involves deleting a column, |
| 821 | but for M2Ms may involve deleting a table. |
| 822 | """ |
| 823 | # Special-case implicit M2M tables |
| 824 | if field.many_to_many and field.remote_field.through._meta.auto_created: |
| 825 | return self.delete_model(field.remote_field.through) |
| 826 | # It might not actually have a column behind it |
| 827 | if field.db_parameters(connection=self.connection)["type"] is None: |
| 828 | return |
| 829 | # Drop any FK constraints, MySQL requires explicit deletion |
| 830 | if field.remote_field: |
| 831 | fk_names = self._constraint_names(model, [field.column], foreign_key=True) |
| 832 | for fk_name in fk_names: |
| 833 | self.execute(self._delete_fk_sql(model, fk_name)) |
| 834 | # Delete the column |
| 835 | sql = self.sql_delete_column % { |
| 836 | "table": self.quote_name(model._meta.db_table), |
| 837 | "column": self.quote_name(field.column), |
| 838 | } |
| 839 | self.execute(sql) |
| 840 | # Reset connection if required |
| 841 | if self.connection.features.connection_persists_old_columns: |
| 842 | self.connection.close() |
| 843 | # Remove all deferred statements referencing the deleted column. |
| 844 | for sql in list(self.deferred_sql): |
| 845 | if isinstance(sql, Statement) and sql.references_column( |
| 846 | model._meta.db_table, field.column |
| 847 | ): |
| 848 | self.deferred_sql.remove(sql) |
| 849 | |
| 850 | def alter_field(self, model, old_field, new_field, strict=False): |
| 851 | """ |
nothing calls this directly
no test coverage detected