1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Rename ExportTemplate.content_types to object_types & use ObjectType proxy

This commit is contained in:
Jeremy Stretch
2024-03-01 15:54:21 -05:00
parent e51d71d7e6
commit bef17e5a95
15 changed files with 54 additions and 41 deletions

View File

@ -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',
]

View File

@ -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():

View File

@ -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',
)

View File

@ -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')

View File

@ -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')),
)

View File

@ -71,7 +71,7 @@ class ExportTemplateType(ObjectType):
class Meta:
model = models.ExportTemplate
exclude = ('content_types', )
exclude = ('object_types', )
filterset_class = filtersets.ExportTemplateFilterSet

View File

@ -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'),
),
]

View File

@ -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.')
)

View File

@ -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',
)

View File

@ -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):

View File

@ -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):

View File

@ -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}",

View File

@ -70,9 +70,9 @@
<div class="card">
<h5 class="card-header">{% trans "Assigned Models" %}</h5>
<table class="table table-hover attr-table">
{% for ct in object.content_types.all %}
{% for object_type in object.object_types.all %}
<tr>
<td>{{ ct }}</td>
<td>{{ object_type }}</td>
</tr>
{% endfor %}
</table>

View File

@ -25,7 +25,7 @@
<hr class="dropdown-divider">
</li>
<li>
<a class="dropdown-item" href="{% url 'extras:exporttemplate_add' %}?content_types={{ content_type.pk }}">{% trans "Add export template" %}...</a>
<a class="dropdown-item" href="{% url 'extras:exporttemplate_add' %}?object_types={{ object_type.pk }}">{% trans "Add export template" %}...</a>
</li>
{% endif %}
</ul>

View File

@ -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,