Create a field on a model. Usually involves adding a column, but may involve adding a table instead (for M2M fields).
(self, model, field)
| 727 | ) |
| 728 | |
| 729 | def add_field(self, model, field): |
| 730 | """ |
| 731 | Create a field on a model. Usually involves adding a column, but may |
| 732 | involve adding a table instead (for M2M fields). |
| 733 | """ |
| 734 | # Special-case implicit M2M tables |
| 735 | if field.many_to_many and field.remote_field.through._meta.auto_created: |
| 736 | return self.create_model(field.remote_field.through) |
| 737 | # Get the column's definition |
| 738 | definition, params = self.column_sql(model, field, include_default=True) |
| 739 | # It might not actually have a column behind it |
| 740 | if definition is None: |
| 741 | return |
| 742 | if col_type_suffix := field.db_type_suffix(connection=self.connection): |
| 743 | definition += f" {col_type_suffix}" |
| 744 | # Check constraints can go on the column SQL here |
| 745 | db_params = field.db_parameters(connection=self.connection) |
| 746 | if db_params["check"]: |
| 747 | definition += " " + self.sql_check_constraint % db_params |
| 748 | if ( |
| 749 | field.remote_field |
| 750 | and self.connection.features.supports_foreign_keys |
| 751 | and field.db_constraint |
| 752 | ): |
| 753 | constraint_suffix = "_fk_%(to_table)s_%(to_column)s" |
| 754 | # Add FK constraint inline, if supported. |
| 755 | if self.sql_create_column_inline_fk: |
| 756 | to_table = field.remote_field.model._meta.db_table |
| 757 | to_column = field.remote_field.model._meta.get_field( |
| 758 | field.remote_field.field_name |
| 759 | ).column |
| 760 | namespace, _ = split_identifier(model._meta.db_table) |
| 761 | definition += " " + self.sql_create_column_inline_fk % { |
| 762 | "name": self._fk_constraint_name(model, field, constraint_suffix), |
| 763 | "namespace": ( |
| 764 | "%s." % self.quote_name(namespace) if namespace else "" |
| 765 | ), |
| 766 | "column": self.quote_name(field.column), |
| 767 | "to_table": self.quote_name(to_table), |
| 768 | "to_column": self.quote_name(to_column), |
| 769 | "deferrable": self.connection.ops.deferrable_sql(), |
| 770 | "on_delete_db": self._create_on_delete_sql(model, field), |
| 771 | } |
| 772 | # Otherwise, add FK constraints later. |
| 773 | else: |
| 774 | self.deferred_sql.append( |
| 775 | self._create_fk_sql(model, field, constraint_suffix) |
| 776 | ) |
| 777 | # Build the SQL and run it |
| 778 | sql = self.sql_create_column % { |
| 779 | "table": self.quote_name(model._meta.db_table), |
| 780 | "column": self.quote_name(field.column), |
| 781 | "definition": definition, |
| 782 | } |
| 783 | # Prevent using [] as params, in the case a literal '%' is used in the |
| 784 | # definition on backends that don't support parametrized DDL. |
| 785 | self.execute(sql, params or None) |
| 786 | # Drop the default if we need to |
nothing calls this directly
no test coverage detected