@@ -115,6 +115,12 @@ def get_absolute_url(self):
115115 },
116116 )
117117
118+ def get_list_url (self ):
119+ return reverse (
120+ "plugins:netbox_custom_objects:customobject_list" ,
121+ kwargs = {"custom_object_type" : self .custom_object_type .name .lower ()},
122+ )
123+
118124
119125class CustomObjectType (NetBoxModel ):
120126 # Class-level cache for generated models
@@ -1130,7 +1136,86 @@ def save(self, *args, **kwargs):
11301136 else :
11311137 old_field = field_type .get_model_field (self .original )
11321138 old_field .contribute_to_class (model , self ._original_name )
1133- schema_editor .alter_field (model , old_field , model_field )
1139+
1140+ # Special handling for MultiObject fields when the name changes
1141+ if (self .type == CustomFieldTypeChoices .TYPE_MULTIOBJECT and
1142+ self .name != self ._original_name ):
1143+ # For renamed MultiObject fields, we just need to rename the through table
1144+ old_through_table_name = self .original .through_table_name
1145+ new_through_table_name = self .through_table_name
1146+
1147+ # Check if old through table exists
1148+ with connection .cursor () as cursor :
1149+ tables = connection .introspection .table_names (cursor )
1150+ old_table_exists = old_through_table_name in tables
1151+
1152+ if old_table_exists :
1153+ # Create temporary models to represent the old and new through table states
1154+ old_through_meta = type (
1155+ "Meta" ,
1156+ (),
1157+ {
1158+ "db_table" : old_through_table_name ,
1159+ "app_label" : APP_LABEL ,
1160+ "managed" : True ,
1161+ },
1162+ )
1163+ old_through_model = type (
1164+ f"TempOld{ self .original .through_model_name } " ,
1165+ (models .Model ,),
1166+ {
1167+ "__module__" : "netbox_custom_objects.models" ,
1168+ "Meta" : old_through_meta ,
1169+ "id" : models .AutoField (primary_key = True ),
1170+ "source" : models .ForeignKey (
1171+ model , on_delete = models .CASCADE ,
1172+ db_column = "source_id" , related_name = "+"
1173+ ),
1174+ "target" : models .ForeignKey (
1175+ model , on_delete = models .CASCADE ,
1176+ db_column = "target_id" , related_name = "+"
1177+ ),
1178+ },
1179+ )
1180+
1181+ new_through_meta = type (
1182+ "Meta" ,
1183+ (),
1184+ {
1185+ "db_table" : new_through_table_name ,
1186+ "app_label" : APP_LABEL ,
1187+ "managed" : True ,
1188+ },
1189+ )
1190+ new_through_model = type (
1191+ f"TempNew{ self .through_model_name } " ,
1192+ (models .Model ,),
1193+ {
1194+ "__module__" : "netbox_custom_objects.models" ,
1195+ "Meta" : new_through_meta ,
1196+ "id" : models .AutoField (primary_key = True ),
1197+ "source" : models .ForeignKey (
1198+ model , on_delete = models .CASCADE ,
1199+ db_column = "source_id" , related_name = "+"
1200+ ),
1201+ "target" : models .ForeignKey (
1202+ model , on_delete = models .CASCADE ,
1203+ db_column = "target_id" , related_name = "+"
1204+ ),
1205+ },
1206+ )
1207+
1208+ # Rename the table using Django's schema editor
1209+ schema_editor .alter_db_table (old_through_model , old_through_table_name , new_through_table_name )
1210+ else :
1211+ # No old table exists, create the new through table
1212+ field_type .create_m2m_table (self , model , self .name )
1213+
1214+ # Alter the field normally (this updates the field definition)
1215+ schema_editor .alter_field (model , old_field , model_field )
1216+ else :
1217+ # Normal field alteration
1218+ schema_editor .alter_field (model , old_field , model_field )
11341219
11351220 # Clear and refresh the model cache for this CustomObjectType when a field is modified
11361221 self .custom_object_type .clear_model_cache (self .custom_object_type .id )
0 commit comments