Allow a field's type, uniqueness, nullability, default, column, constraints, etc. to be modified. `old_field` is required to compute the necessary changes. If `strict` is True, raise errors if the old column does not match `old_field` precisely.
(self, model, old_field, new_field, strict=False)
| 848 | self.deferred_sql.remove(sql) |
| 849 | |
| 850 | def alter_field(self, model, old_field, new_field, strict=False): |
| 851 | """ |
| 852 | Allow a field's type, uniqueness, nullability, default, column, |
| 853 | constraints, etc. to be modified. |
| 854 | `old_field` is required to compute the necessary changes. |
| 855 | If `strict` is True, raise errors if the old column does not match |
| 856 | `old_field` precisely. |
| 857 | """ |
| 858 | if not self._field_should_be_altered(old_field, new_field): |
| 859 | return |
| 860 | # Ensure this field is even column-based |
| 861 | old_db_params = old_field.db_parameters(connection=self.connection) |
| 862 | old_type = old_db_params["type"] |
| 863 | new_db_params = new_field.db_parameters(connection=self.connection) |
| 864 | new_type = new_db_params["type"] |
| 865 | modifying_generated_field = False |
| 866 | if (old_type is None and old_field.remote_field is None) or ( |
| 867 | new_type is None and new_field.remote_field is None |
| 868 | ): |
| 869 | raise ValueError( |
| 870 | "Cannot alter field %s into %s - they do not properly define " |
| 871 | "db_type (are you using a badly-written custom field?)" |
| 872 | % (old_field, new_field), |
| 873 | ) |
| 874 | elif ( |
| 875 | old_type is None |
| 876 | and new_type is None |
| 877 | and ( |
| 878 | old_field.remote_field.through |
| 879 | and new_field.remote_field.through |
| 880 | and old_field.remote_field.through._meta.auto_created |
| 881 | and new_field.remote_field.through._meta.auto_created |
| 882 | ) |
| 883 | ): |
| 884 | return self._alter_many_to_many(model, old_field, new_field, strict) |
| 885 | elif ( |
| 886 | old_type is None |
| 887 | and new_type is None |
| 888 | and ( |
| 889 | old_field.remote_field.through |
| 890 | and new_field.remote_field.through |
| 891 | and not old_field.remote_field.through._meta.auto_created |
| 892 | and not new_field.remote_field.through._meta.auto_created |
| 893 | ) |
| 894 | ): |
| 895 | # Both sides have through models; this is a no-op. |
| 896 | return |
| 897 | elif old_type is None or new_type is None: |
| 898 | raise ValueError( |
| 899 | "Cannot alter field %s into %s - they are not compatible types " |
| 900 | "(you cannot alter to or from M2M fields, or add or remove " |
| 901 | "through= on M2M fields)" % (old_field, new_field) |
| 902 | ) |
| 903 | elif old_field.generated != new_field.generated or ( |
| 904 | new_field.generated and old_field.db_persist != new_field.db_persist |
| 905 | ): |
| 906 | modifying_generated_field = True |
| 907 | elif new_field.generated: |
no test coverage detected