Devise a mechanism for referencing all user-facing models #8441

Closed
opened 2025-12-29 20:36:44 +01:00 by adam · 1 comment
Owner

Originally created by @jeremystretch on GitHub (Aug 9, 2023).

Originally assigned to: @jeremystretch on GitHub.

Proposed Changes

Devise and implement a mechanism for filtering the content types for all user-facing models in NetBox. This includes essentially all of the models which can be manipulated directly via the UI or API, and excludes those "behind the scenes" models which cannot.

Justification

There are several instances where we currently work around this limitation. Below are some that I have identified; there are likely others to address as well.

  1. Retrieving content types for e.g. the object list dashboard widget:
# extras/dashboard/widgets.py
def get_content_type_labels():
    return [
        (content_type_identifier(ct), content_type_name(ct))
        for ct in ContentType.objects.filter(
            FeatureQuery('export_templates').get_query() | Q(app_label='extras', model='objectchange') |
            Q(app_label='extras', model='configcontext')
        ).order_by('app_label', 'model')
    ]
  1. Limiting object_type choices on CustomField import:
# extras/forms/bulk_import.py
class CustomFieldImportForm(CSVModelForm):
    ...
    object_type = CSVContentTypeField(
        label=_('Object type'),
        queryset=ContentType.objects.all(),
        limit_choices_to=FeatureQuery('custom_fields'),  # Should be generic
        required=False,
        help_text=_("Object type (for object or multi-object fields)")
    )
  1. Filtering for SavedFilter objects:
# extras/forms/filtersets.py
class SavedFilterFilterForm(SavedFiltersMixin, FilterForm):
    content_types = ContentTypeMultipleChoiceField(
        label=_('Content types'),
        queryset=ContentType.objects.filter(FeatureQuery('export_templates').get_query()),  # Should be generic
        required=False
    )
  1. Limiting object_type choices on CustomField edit:
# extras/forms/model_forms.py
class CustomFieldForm(BootstrapMixin, forms.ModelForm):
    object_type = ContentTypeChoiceField(
        label=_('Object type'),
        queryset=ContentType.objects.all(),
        # TODO: Come up with a canonical way to register suitable models
        limit_choices_to=FeatureQuery('webhooks').get_query() | Q(app_label='auth', model__in=['user', 'group']),
        required=False,
        help_text=_("Type of the related object (for object/multi-object fields only)")
    )
Originally created by @jeremystretch on GitHub (Aug 9, 2023). Originally assigned to: @jeremystretch on GitHub. ### Proposed Changes Devise and implement a mechanism for filtering the content types for all user-facing models in NetBox. This includes essentially all of the models which can be manipulated directly via the UI or API, and excludes those "behind the scenes" models which cannot. ### Justification There are several instances where we currently work around this limitation. Below are some that I have identified; there are likely others to address as well. 1. Retrieving content types for e.g. the object list dashboard widget: ```python # extras/dashboard/widgets.py def get_content_type_labels(): return [ (content_type_identifier(ct), content_type_name(ct)) for ct in ContentType.objects.filter( FeatureQuery('export_templates').get_query() | Q(app_label='extras', model='objectchange') | Q(app_label='extras', model='configcontext') ).order_by('app_label', 'model') ] ``` 2. Limiting `object_type` choices on CustomField import: ```python # extras/forms/bulk_import.py class CustomFieldImportForm(CSVModelForm): ... object_type = CSVContentTypeField( label=_('Object type'), queryset=ContentType.objects.all(), limit_choices_to=FeatureQuery('custom_fields'), # Should be generic required=False, help_text=_("Object type (for object or multi-object fields)") ) ``` 3. Filtering for SavedFilter objects: ```python # extras/forms/filtersets.py class SavedFilterFilterForm(SavedFiltersMixin, FilterForm): content_types = ContentTypeMultipleChoiceField( label=_('Content types'), queryset=ContentType.objects.filter(FeatureQuery('export_templates').get_query()), # Should be generic required=False ) ``` 4. Limiting `object_type` choices on CustomField edit: ```python # extras/forms/model_forms.py class CustomFieldForm(BootstrapMixin, forms.ModelForm): object_type = ContentTypeChoiceField( label=_('Object type'), queryset=ContentType.objects.all(), # TODO: Come up with a canonical way to register suitable models limit_choices_to=FeatureQuery('webhooks').get_query() | Q(app_label='auth', model__in=['user', 'group']), required=False, help_text=_("Type of the related object (for object/multi-object fields only)") ) ```
adam added the status: acceptedtype: housekeeping labels 2025-12-29 20:36:44 +01:00
adam closed this issue 2025-12-29 20:36:45 +01:00
Author
Owner

@jeremystretch commented on GitHub (Nov 3, 2023):

Another instance where this is needed: Populating model classes in ConfigTemplate context.

# extras/models/configs.py
# Populate the default template context with NetBox model classes, namespaced by app
# TODO: Devise a canonical mechanism for identifying the models to include (see #13427)
for app, model_names in registry['model_features']['custom_fields'].items():
    _context.setdefault(app, {})
    for model_name in model_names:
        model = apps.get_registered_model(app, model_name)
        _context[app][model.__name__] = model
@jeremystretch commented on GitHub (Nov 3, 2023): Another instance where this is needed: Populating model classes in ConfigTemplate context. ```python # extras/models/configs.py # Populate the default template context with NetBox model classes, namespaced by app # TODO: Devise a canonical mechanism for identifying the models to include (see #13427) for app, model_names in registry['model_features']['custom_fields'].items(): _context.setdefault(app, {}) for model_name in model_names: model = apps.get_registered_model(app, model_name) _context[app][model.__name__] = model ```
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#8441