Shortcut to transform a model from old_model into new_model This follows the correct procedure to perform non-rename or column addition operations based on SQLite's documentation https://www.sqlite.org/lang_altertable.html#caution The essential steps are:
(
self, model, create_field=None, delete_field=None, alter_fields=None
)
| 78 | return self.quote_value(value) |
| 79 | |
| 80 | def _remake_table( |
| 81 | self, model, create_field=None, delete_field=None, alter_fields=None |
| 82 | ): |
| 83 | """ |
| 84 | Shortcut to transform a model from old_model into new_model |
| 85 | |
| 86 | This follows the correct procedure to perform non-rename or column |
| 87 | addition operations based on SQLite's documentation |
| 88 | |
| 89 | https://www.sqlite.org/lang_altertable.html#caution |
| 90 | |
| 91 | The essential steps are: |
| 92 | 1. Create a table with the updated definition called "new__app_model" |
| 93 | 2. Copy the data from the existing "app_model" table to the new table |
| 94 | 3. Drop the "app_model" table |
| 95 | 4. Rename the "new__app_model" table to "app_model" |
| 96 | 5. Restore any index of the previous "app_model" table. |
| 97 | """ |
| 98 | |
| 99 | # Self-referential fields must be recreated rather than copied from |
| 100 | # the old model to ensure their remote_field.field_name doesn't refer |
| 101 | # to an altered field. |
| 102 | def is_self_referential(f): |
| 103 | return f.is_relation and f.remote_field.model is model |
| 104 | |
| 105 | # Work out the new fields dict / mapping |
| 106 | body = { |
| 107 | f.name: f.clone() if is_self_referential(f) else f |
| 108 | for f in model._meta.local_concrete_fields |
| 109 | } |
| 110 | |
| 111 | # Since CompositePrimaryKey is not a concrete field (column is None), |
| 112 | # it's not copied by default. |
| 113 | pk = model._meta.pk |
| 114 | if isinstance(pk, CompositePrimaryKey): |
| 115 | body[pk.name] = pk.clone() |
| 116 | |
| 117 | # Since mapping might mix column names and default values, |
| 118 | # its values must be already quoted. |
| 119 | mapping = { |
| 120 | f.column: self.quote_name(f.column) |
| 121 | for f in model._meta.local_concrete_fields |
| 122 | if f.generated is False |
| 123 | } |
| 124 | # This maps field names (not columns) for things like unique_together |
| 125 | rename_mapping = {} |
| 126 | # If any of the new or altered fields is introducing a new PK, |
| 127 | # remove the old one |
| 128 | restore_pk_field = None |
| 129 | alter_fields = alter_fields or [] |
| 130 | if getattr(create_field, "primary_key", False) or any( |
| 131 | getattr(new_field, "primary_key", False) for _, new_field in alter_fields |
| 132 | ): |
| 133 | for name, field in list(body.items()): |
| 134 | if field.primary_key and not any( |
| 135 | # Do not remove the old primary key when an altered field |
| 136 | # that introduces a primary key is the same field. |
| 137 | name == new_field.name |
no test coverage detected