From bef17e5a9511fce2646d669be7f4ce6f583e7319 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 1 Mar 2024 15:54:21 -0500 Subject: [PATCH] Rename ExportTemplate.content_types to object_types & use ObjectType proxy --- netbox/extras/api/serializers.py | 4 ++-- netbox/extras/filtersets.py | 8 ++++---- netbox/extras/forms/bulk_import.py | 6 +++--- netbox/extras/forms/filtersets.py | 4 ++-- netbox/extras/forms/model_forms.py | 6 +++--- netbox/extras/graphql/types.py | 2 +- .../extras/migrations/0111_rename_content_types.py | 12 ++++++++++++ netbox/extras/models/models.py | 4 ++-- netbox/extras/tables/tables.py | 8 ++++---- netbox/extras/tests/test_api.py | 8 ++++---- netbox/extras/tests/test_filtersets.py | 10 +++++----- netbox/extras/tests/test_views.py | 8 ++++---- netbox/templates/extras/exporttemplate.html | 4 ++-- netbox/utilities/templates/buttons/export.html | 2 +- netbox/utilities/templatetags/buttons.py | 9 +++++---- 15 files changed, 54 insertions(+), 41 deletions(-) diff --git a/netbox/extras/api/serializers.py b/netbox/extras/api/serializers.py index 32b708fcc..3871fcc70 100644 --- a/netbox/extras/api/serializers.py +++ b/netbox/extras/api/serializers.py @@ -216,7 +216,7 @@ class CustomLinkSerializer(ValidatedModelSerializer): class ExportTemplateSerializer(ValidatedModelSerializer): url = serializers.HyperlinkedIdentityField(view_name='extras-api:exporttemplate-detail') - content_types = ContentTypeField( + object_types = ContentTypeField( queryset=ObjectType.objects.with_feature('export_templates'), many=True ) @@ -230,7 +230,7 @@ class ExportTemplateSerializer(ValidatedModelSerializer): class Meta: model = ExportTemplate fields = [ - 'id', 'url', 'display', 'content_types', 'name', 'description', 'template_code', 'mime_type', + 'id', 'url', 'display', 'object_types', 'name', 'description', 'template_code', 'mime_type', 'file_extension', 'as_attachment', 'data_source', 'data_path', 'data_file', 'data_synced', 'created', 'last_updated', ] diff --git a/netbox/extras/filtersets.py b/netbox/extras/filtersets.py index d03d134be..83978806a 100644 --- a/netbox/extras/filtersets.py +++ b/netbox/extras/filtersets.py @@ -217,10 +217,10 @@ class ExportTemplateFilterSet(BaseFilterSet): method='search', label=_('Search'), ) - content_type_id = MultiValueNumberFilter( - field_name='content_types__id' + object_types_id = MultiValueNumberFilter( + field_name='object_types__id' ) - content_types = ContentTypeFilter() + object_types = ContentTypeFilter() data_source_id = django_filters.ModelMultipleChoiceFilter( queryset=DataSource.objects.all(), label=_('Data source (ID)'), @@ -232,7 +232,7 @@ class ExportTemplateFilterSet(BaseFilterSet): class Meta: model = ExportTemplate - fields = ['id', 'content_types', 'name', 'description', 'data_synced'] + fields = ['id', 'object_types', 'name', 'description', 'data_synced'] def search(self, queryset, name, value): if not value.strip(): diff --git a/netbox/extras/forms/bulk_import.py b/netbox/extras/forms/bulk_import.py index cbb7b4e44..9c68c7ba3 100644 --- a/netbox/extras/forms/bulk_import.py +++ b/netbox/extras/forms/bulk_import.py @@ -126,8 +126,8 @@ class CustomLinkImportForm(CSVModelForm): class ExportTemplateImportForm(CSVModelForm): - content_types = CSVMultipleContentTypeField( - label=_('Content types'), + object_types = CSVMultipleContentTypeField( + label=_('Object types'), queryset=ObjectType.objects.with_feature('export_templates'), help_text=_("One or more assigned object types") ) @@ -135,7 +135,7 @@ class ExportTemplateImportForm(CSVModelForm): class Meta: model = ExportTemplate fields = ( - 'name', 'content_types', 'description', 'mime_type', 'file_extension', 'as_attachment', 'template_code', + 'name', 'object_types', 'description', 'mime_type', 'file_extension', 'as_attachment', 'template_code', ) diff --git a/netbox/extras/forms/filtersets.py b/netbox/extras/forms/filtersets.py index f19695f57..daad010c1 100644 --- a/netbox/extras/forms/filtersets.py +++ b/netbox/extras/forms/filtersets.py @@ -139,7 +139,7 @@ class ExportTemplateFilterForm(SavedFiltersMixin, FilterForm): fieldsets = ( (None, ('q', 'filter_id')), (_('Data'), ('data_source_id', 'data_file_id')), - (_('Attributes'), ('content_type_id', 'mime_type', 'file_extension', 'as_attachment')), + (_('Attributes'), ('object_types_id', 'mime_type', 'file_extension', 'as_attachment')), ) data_source_id = DynamicModelMultipleChoiceField( queryset=DataSource.objects.all(), @@ -154,7 +154,7 @@ class ExportTemplateFilterForm(SavedFiltersMixin, FilterForm): 'source_id': '$data_source_id' } ) - content_type_id = ContentTypeMultipleChoiceField( + object_types_id = ContentTypeMultipleChoiceField( queryset=ObjectType.objects.with_feature('export_templates'), required=False, label=_('Content types') diff --git a/netbox/extras/forms/model_forms.py b/netbox/extras/forms/model_forms.py index 9423e35e2..95af8fb3b 100644 --- a/netbox/extras/forms/model_forms.py +++ b/netbox/extras/forms/model_forms.py @@ -151,8 +151,8 @@ class CustomLinkForm(forms.ModelForm): class ExportTemplateForm(SyncedDataMixin, forms.ModelForm): - content_types = ContentTypeMultipleChoiceField( - label=_('Content types'), + object_types = ContentTypeMultipleChoiceField( + label=_('Object types'), queryset=ObjectType.objects.with_feature('export_templates') ) template_code = forms.CharField( @@ -162,7 +162,7 @@ class ExportTemplateForm(SyncedDataMixin, forms.ModelForm): ) fieldsets = ( - (_('Export Template'), ('name', 'content_types', 'description', 'template_code')), + (_('Export Template'), ('name', 'object_types', 'description', 'template_code')), (_('Data Source'), ('data_source', 'data_file', 'auto_sync_enabled')), (_('Rendering'), ('mime_type', 'file_extension', 'as_attachment')), ) diff --git a/netbox/extras/graphql/types.py b/netbox/extras/graphql/types.py index 15ef76b6b..1000925bb 100644 --- a/netbox/extras/graphql/types.py +++ b/netbox/extras/graphql/types.py @@ -71,7 +71,7 @@ class ExportTemplateType(ObjectType): class Meta: model = models.ExportTemplate - exclude = ('content_types', ) + exclude = ('object_types', ) filterset_class = filtersets.ExportTemplateFilterSet diff --git a/netbox/extras/migrations/0111_rename_content_types.py b/netbox/extras/migrations/0111_rename_content_types.py index f44b01e34..87f721589 100644 --- a/netbox/extras/migrations/0111_rename_content_types.py +++ b/netbox/extras/migrations/0111_rename_content_types.py @@ -50,4 +50,16 @@ class Migration(migrations.Migration): name='object_types', field=models.ManyToManyField(related_name='event_rules', to='core.objecttype'), ), + + # Export templates + migrations.RenameField( + model_name='exporttemplate', + old_name='content_types', + new_name='object_types', + ), + migrations.AlterField( + model_name='exporttemplate', + name='object_types', + field=models.ManyToManyField(related_name='export_templates', to='core.objecttype'), + ), ] diff --git a/netbox/extras/models/models.py b/netbox/extras/models/models.py index bfc11b7c5..77e703dc0 100644 --- a/netbox/extras/models/models.py +++ b/netbox/extras/models/models.py @@ -409,8 +409,8 @@ class CustomLink(CloningMixin, ExportTemplatesMixin, ChangeLoggedModel): class ExportTemplate(SyncedDataMixin, CloningMixin, ExportTemplatesMixin, ChangeLoggedModel): - content_types = models.ManyToManyField( - to='contenttypes.ContentType', + object_types = models.ManyToManyField( + to='core.ObjectType', related_name='export_templates', help_text=_('The object type(s) to which this template applies.') ) diff --git a/netbox/extras/tables/tables.py b/netbox/extras/tables/tables.py index 7775916b9..abc73c5ba 100644 --- a/netbox/extras/tables/tables.py +++ b/netbox/extras/tables/tables.py @@ -139,8 +139,8 @@ class ExportTemplateTable(NetBoxTable): verbose_name=_('Name'), linkify=True ) - content_types = columns.ContentTypesColumn( - verbose_name=_('Content Types'), + object_types = columns.ContentTypesColumn( + verbose_name=_('Object Types'), ) as_attachment = columns.BooleanColumn( verbose_name=_('As Attachment'), @@ -161,11 +161,11 @@ class ExportTemplateTable(NetBoxTable): class Meta(NetBoxTable.Meta): model = ExportTemplate fields = ( - 'pk', 'id', 'name', 'content_types', 'description', 'mime_type', 'file_extension', 'as_attachment', + 'pk', 'id', 'name', 'object_types', 'description', 'mime_type', 'file_extension', 'as_attachment', 'data_source', 'data_file', 'data_synced', 'created', 'last_updated', ) default_columns = ( - 'pk', 'name', 'content_types', 'description', 'mime_type', 'file_extension', 'as_attachment', 'is_synced', + 'pk', 'name', 'object_types', 'description', 'mime_type', 'file_extension', 'as_attachment', 'is_synced', ) diff --git a/netbox/extras/tests/test_api.py b/netbox/extras/tests/test_api.py index 7bed486a0..34a1bdc40 100644 --- a/netbox/extras/tests/test_api.py +++ b/netbox/extras/tests/test_api.py @@ -458,17 +458,17 @@ class ExportTemplateTest(APIViewTestCases.APIViewTestCase): brief_fields = ['description', 'display', 'id', 'name', 'url'] create_data = [ { - 'content_types': ['dcim.device'], + 'object_types': ['dcim.device'], 'name': 'Test Export Template 4', 'template_code': '{% for obj in queryset %}{{ obj.name }}\n{% endfor %}', }, { - 'content_types': ['dcim.device'], + 'object_types': ['dcim.device'], 'name': 'Test Export Template 5', 'template_code': '{% for obj in queryset %}{{ obj.name }}\n{% endfor %}', }, { - 'content_types': ['dcim.device'], + 'object_types': ['dcim.device'], 'name': 'Test Export Template 6', 'template_code': '{% for obj in queryset %}{{ obj.name }}\n{% endfor %}', }, @@ -495,7 +495,7 @@ class ExportTemplateTest(APIViewTestCases.APIViewTestCase): ) ExportTemplate.objects.bulk_create(export_templates) for et in export_templates: - et.content_types.set([ContentType.objects.get_for_model(Device)]) + et.object_types.set([ObjectType.objects.get_for_model(Device)]) class TagTest(APIViewTestCases.APIViewTestCase): diff --git a/netbox/extras/tests/test_filtersets.py b/netbox/extras/tests/test_filtersets.py index 43ee605fb..af079786b 100644 --- a/netbox/extras/tests/test_filtersets.py +++ b/netbox/extras/tests/test_filtersets.py @@ -639,7 +639,7 @@ class ExportTemplateTestCase(TestCase, BaseFilterSetTests): @classmethod def setUpTestData(cls): - content_types = ContentType.objects.filter(model__in=['site', 'rack', 'device']) + object_types = ObjectType.objects.filter(model__in=['site', 'rack', 'device']) export_templates = ( ExportTemplate(name='Export Template 1', template_code='TESTING', description='foobar1'), @@ -648,7 +648,7 @@ class ExportTemplateTestCase(TestCase, BaseFilterSetTests): ) ExportTemplate.objects.bulk_create(export_templates) for i, et in enumerate(export_templates): - et.content_types.set([content_types[i]]) + et.object_types.set([object_types[i]]) def test_q(self): params = {'q': 'foobar1'} @@ -658,10 +658,10 @@ class ExportTemplateTestCase(TestCase, BaseFilterSetTests): params = {'name': ['Export Template 1', 'Export Template 2']} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) - def test_content_types(self): - params = {'content_types': 'dcim.site'} + def test_object_types(self): + params = {'object_types': 'dcim.site'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) - params = {'content_type_id': [ContentType.objects.get_for_model(Site).pk]} + params = {'object_types_id': [ContentType.objects.get_for_model(Site).pk]} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) def test_description(self): diff --git a/netbox/extras/tests/test_views.py b/netbox/extras/tests/test_views.py index ba7cd0818..02114d035 100644 --- a/netbox/extras/tests/test_views.py +++ b/netbox/extras/tests/test_views.py @@ -303,7 +303,7 @@ class ExportTemplateTestCase(ViewTestCases.PrimaryObjectViewTestCase): @classmethod def setUpTestData(cls): - site_ct = ContentType.objects.get_for_model(Site) + site_type = ObjectType.objects.get_for_model(Site) TEMPLATE_CODE = """{% for object in queryset %}{{ object }}{% endfor %}""" export_templates = ( @@ -313,16 +313,16 @@ class ExportTemplateTestCase(ViewTestCases.PrimaryObjectViewTestCase): ) ExportTemplate.objects.bulk_create(export_templates) for et in export_templates: - et.content_types.set([site_ct]) + et.object_types.set([site_type]) cls.form_data = { 'name': 'Export Template X', - 'content_types': [site_ct.pk], + 'object_types': [site_type.pk], 'template_code': TEMPLATE_CODE, } cls.csv_data = ( - "name,content_types,template_code", + "name,object_types,template_code", f"Export Template 4,dcim.site,{TEMPLATE_CODE}", f"Export Template 5,dcim.site,{TEMPLATE_CODE}", f"Export Template 6,dcim.site,{TEMPLATE_CODE}", diff --git a/netbox/templates/extras/exporttemplate.html b/netbox/templates/extras/exporttemplate.html index 0648a8191..16dd49ee2 100644 --- a/netbox/templates/extras/exporttemplate.html +++ b/netbox/templates/extras/exporttemplate.html @@ -70,9 +70,9 @@
{% trans "Assigned Models" %}
- {% for ct in object.content_types.all %} + {% for object_type in object.object_types.all %} - + {% endfor %}
{{ ct }}{{ object_type }}
diff --git a/netbox/utilities/templates/buttons/export.html b/netbox/utilities/templates/buttons/export.html index d24be88f7..2085356fa 100644 --- a/netbox/utilities/templates/buttons/export.html +++ b/netbox/utilities/templates/buttons/export.html @@ -25,7 +25,7 @@
  • - {% trans "Add export template" %}... + {% trans "Add export template" %}...
  • {% endif %} diff --git a/netbox/utilities/templatetags/buttons.py b/netbox/utilities/templatetags/buttons.py index 828af3b43..c0870d585 100644 --- a/netbox/utilities/templatetags/buttons.py +++ b/netbox/utilities/templatetags/buttons.py @@ -2,6 +2,7 @@ from django import template from django.contrib.contenttypes.models import ContentType from django.urls import NoReverseMatch, reverse +from core.models import ObjectType from extras.models import Bookmark, ExportTemplate from utilities.utils import get_viewname, prepare_cloned_fields @@ -132,18 +133,18 @@ def import_button(model, action='import'): @register.inclusion_tag('buttons/export.html', takes_context=True) def export_button(context, model): - content_type = ContentType.objects.get_for_model(model) + object_type = ObjectType.objects.get_for_model(model) user = context['request'].user # Determine if the "all data" export returns CSV or YAML - data_format = 'YAML' if hasattr(content_type.model_class(), 'to_yaml') else 'CSV' + data_format = 'YAML' if hasattr(object_type.model_class(), 'to_yaml') else 'CSV' # Retrieve all export templates for this model - export_templates = ExportTemplate.objects.restrict(user, 'view').filter(content_types=content_type) + export_templates = ExportTemplate.objects.restrict(user, 'view').filter(object_types=object_type) return { 'perms': context['perms'], - 'content_type': content_type, + 'object_type': object_type, 'url_params': context['request'].GET.urlencode() if context['request'].GET else '', 'export_templates': export_templates, 'data_format': data_format,