|
2 | 2 |
|
3 | 3 | from django.contrib.contenttypes.models import ContentType |
4 | 4 | from django.db.models import Q |
| 5 | +from django.db.utils import OperationalError, ProgrammingError |
5 | 6 | from django.shortcuts import get_object_or_404, render |
6 | 7 | from django.views.generic import View |
7 | 8 | from extras.choices import CustomFieldTypeChoices, CustomFieldUIVisibleChoices |
@@ -247,32 +248,39 @@ def register_typed_tabs(model_classes, weight): |
247 | 248 | Pre-fetches all relevant CustomObjectTypeFields and groups them. |
248 | 249 | """ |
249 | 250 |
|
250 | | - # Collect all relevant fields |
251 | | - all_fields = CustomObjectTypeField.objects.filter( |
252 | | - type__in=[ |
253 | | - CustomFieldTypeChoices.TYPE_OBJECT, |
254 | | - CustomFieldTypeChoices.TYPE_MULTIOBJECT, |
255 | | - ], |
256 | | - ).select_related("custom_object_type") |
257 | | - |
258 | | - # Group by (content_type_id, custom_object_type_pk) |
259 | | - # -> list of (field_name, field_type) |
260 | | - from collections import defaultdict |
261 | | - |
262 | | - ct_cot_fields = defaultdict(list) |
263 | | - ct_cot_map = {} # (ct_id, cot_pk) -> CustomObjectType |
264 | | - for field in all_fields: |
265 | | - if field.related_object_type_id is None: |
266 | | - continue |
267 | | - key = (field.related_object_type_id, field.custom_object_type_id) |
268 | | - ct_cot_fields[key].append((field.name, field.type)) |
269 | | - ct_cot_map[key] = field.custom_object_type |
270 | | - |
271 | | - # Build a set of content_type_ids we care about |
272 | | - model_ct_map = {} # content_type_id -> model_class |
273 | | - for model_class in model_classes: |
274 | | - ct = ContentType.objects.get_for_model(model_class) |
275 | | - model_ct_map[ct.pk] = model_class |
| 251 | + try: |
| 252 | + # Collect all relevant fields |
| 253 | + all_fields = CustomObjectTypeField.objects.filter( |
| 254 | + type__in=[ |
| 255 | + CustomFieldTypeChoices.TYPE_OBJECT, |
| 256 | + CustomFieldTypeChoices.TYPE_MULTIOBJECT, |
| 257 | + ], |
| 258 | + ).select_related("custom_object_type") |
| 259 | + |
| 260 | + # Group by (content_type_id, custom_object_type_pk) |
| 261 | + # -> list of (field_name, field_type) |
| 262 | + from collections import defaultdict |
| 263 | + |
| 264 | + ct_cot_fields = defaultdict(list) |
| 265 | + ct_cot_map = {} # (ct_id, cot_pk) -> CustomObjectType |
| 266 | + for field in all_fields: |
| 267 | + if field.related_object_type_id is None: |
| 268 | + continue |
| 269 | + key = (field.related_object_type_id, field.custom_object_type_id) |
| 270 | + ct_cot_fields[key].append((field.name, field.type)) |
| 271 | + ct_cot_map[key] = field.custom_object_type |
| 272 | + |
| 273 | + # Build a set of content_type_ids we care about |
| 274 | + model_ct_map = {} # content_type_id -> model_class |
| 275 | + for model_class in model_classes: |
| 276 | + ct = ContentType.objects.get_for_model(model_class) |
| 277 | + model_ct_map[ct.pk] = model_class |
| 278 | + except (OperationalError, ProgrammingError): |
| 279 | + logger.warning( |
| 280 | + "netbox_custom_objects_tab: database unavailable — typed tabs not registered. " |
| 281 | + "Restart NetBox once the database is ready." |
| 282 | + ) |
| 283 | + return |
276 | 284 |
|
277 | 285 | for (ct_id, cot_pk), field_infos in ct_cot_fields.items(): |
278 | 286 | if ct_id not in model_ct_map: |
|
0 commit comments