fix: add m2m field with custom m2m through generate duplicated table when migrating (#393)

* fix: m2m table duplicated when using custom model for through

* Add testcase

* docs: update changelog

* tests: add m2m custom through example test
This commit is contained in:
Waket Zheng
2024-12-17 22:28:06 +08:00
committed by GitHub
parent d8addadb37
commit 4fc7f324d4
3 changed files with 52 additions and 6 deletions

View File

@@ -228,12 +228,18 @@ class Migrate:
indexes.add(cast(Tuple[str, ...], tuple(x)))
return indexes
@staticmethod
def _validate_custom_m2m_through(field: dict) -> None:
# TODO: Check whether field includes required fk columns
pass
@classmethod
def _handle_m2m_fields(
cls, old_model_describe: Dict, new_model_describe: Dict, model, new_models, upgrade=True
) -> None:
old_m2m_fields = cast(List[dict], old_model_describe.get("m2m_fields"))
new_m2m_fields = cast(List[dict], new_model_describe.get("m2m_fields"))
new_tables: Dict[str, dict] = {field["table"]: field for field in new_models.values()}
for action, option, change in get_dict_diff_by_key(old_m2m_fields, new_m2m_fields):
if (option and option[-1] == "nullable") or change[0][0] == "db_constraint":
continue
@@ -247,12 +253,16 @@ class Migrate:
table = new_value.get("through")
if action == "add":
add = False
if upgrade and table not in cls._upgrade_m2m:
cls._upgrade_m2m.append(table)
add = True
elif not upgrade and table not in cls._downgrade_m2m:
cls._downgrade_m2m.append(table)
add = True
if upgrade:
if field := new_tables.get(table):
cls._validate_custom_m2m_through(field)
elif table not in cls._upgrade_m2m:
cls._upgrade_m2m.append(table)
add = True
else:
if table not in cls._downgrade_m2m:
cls._downgrade_m2m.append(table)
add = True
if add:
ref_desc = cast(dict, new_models.get(new_value.get("model_name")))
cls._add_operator(