Skip to content

Commit 6fff0b6

Browse files
authored
#77 Fix rename of MultiObject field (#117)
1 parent 78994a6 commit 6fff0b6

File tree

1 file changed

+80
-1
lines changed

1 file changed

+80
-1
lines changed

netbox_custom_objects/models.py

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1132,7 +1132,86 @@ def save(self, *args, **kwargs):
11321132
else:
11331133
old_field = field_type.get_model_field(self.original)
11341134
old_field.contribute_to_class(model, self._original_name)
1135-
schema_editor.alter_field(model, old_field, model_field)
1135+
1136+
# Special handling for MultiObject fields when the name changes
1137+
if (self.type == CustomFieldTypeChoices.TYPE_MULTIOBJECT and
1138+
self.name != self._original_name):
1139+
# For renamed MultiObject fields, we just need to rename the through table
1140+
old_through_table_name = self.original.through_table_name
1141+
new_through_table_name = self.through_table_name
1142+
1143+
# Check if old through table exists
1144+
with connection.cursor() as cursor:
1145+
tables = connection.introspection.table_names(cursor)
1146+
old_table_exists = old_through_table_name in tables
1147+
1148+
if old_table_exists:
1149+
# Create temporary models to represent the old and new through table states
1150+
old_through_meta = type(
1151+
"Meta",
1152+
(),
1153+
{
1154+
"db_table": old_through_table_name,
1155+
"app_label": APP_LABEL,
1156+
"managed": True,
1157+
},
1158+
)
1159+
old_through_model = type(
1160+
f"TempOld{self.original.through_model_name}",
1161+
(models.Model,),
1162+
{
1163+
"__module__": "netbox_custom_objects.models",
1164+
"Meta": old_through_meta,
1165+
"id": models.AutoField(primary_key=True),
1166+
"source": models.ForeignKey(
1167+
model, on_delete=models.CASCADE,
1168+
db_column="source_id", related_name="+"
1169+
),
1170+
"target": models.ForeignKey(
1171+
model, on_delete=models.CASCADE,
1172+
db_column="target_id", related_name="+"
1173+
),
1174+
},
1175+
)
1176+
1177+
new_through_meta = type(
1178+
"Meta",
1179+
(),
1180+
{
1181+
"db_table": new_through_table_name,
1182+
"app_label": APP_LABEL,
1183+
"managed": True,
1184+
},
1185+
)
1186+
new_through_model = type(
1187+
f"TempNew{self.through_model_name}",
1188+
(models.Model,),
1189+
{
1190+
"__module__": "netbox_custom_objects.models",
1191+
"Meta": new_through_meta,
1192+
"id": models.AutoField(primary_key=True),
1193+
"source": models.ForeignKey(
1194+
model, on_delete=models.CASCADE,
1195+
db_column="source_id", related_name="+"
1196+
),
1197+
"target": models.ForeignKey(
1198+
model, on_delete=models.CASCADE,
1199+
db_column="target_id", related_name="+"
1200+
),
1201+
},
1202+
)
1203+
1204+
# Rename the table using Django's schema editor
1205+
schema_editor.alter_db_table(old_through_model, old_through_table_name, new_through_table_name)
1206+
else:
1207+
# No old table exists, create the new through table
1208+
field_type.create_m2m_table(self, model, self.name)
1209+
1210+
# Alter the field normally (this updates the field definition)
1211+
schema_editor.alter_field(model, old_field, model_field)
1212+
else:
1213+
# Normal field alteration
1214+
schema_editor.alter_field(model, old_field, model_field)
11361215

11371216
# Clear and refresh the model cache for this CustomObjectType when a field is modified
11381217
self.custom_object_type.clear_model_cache(self.custom_object_type.id)

0 commit comments

Comments
 (0)