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

Clean up outdated references to ContentType

This commit is contained in:
Jeremy Stretch
2024-03-04 10:46:34 -05:00
parent d538010069
commit 0419a69ae8
17 changed files with 51 additions and 63 deletions

View File

@ -3,7 +3,6 @@ from zoneinfo import ZoneInfo
import yaml import yaml
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.contrib.contenttypes.models import ContentType
from django.test import override_settings from django.test import override_settings
from django.urls import reverse from django.urls import reverse
from netaddr import EUI from netaddr import EUI
@ -2982,7 +2981,6 @@ class CableTestCase(
tags = create_tags('Alpha', 'Bravo', 'Charlie') tags = create_tags('Alpha', 'Bravo', 'Charlie')
interface_ct = ContentType.objects.get_for_model(Interface)
cls.form_data = { cls.form_data = {
# TODO: Revisit this limitation # TODO: Revisit this limitation
# Changing terminations not supported when editing an existing Cable # Changing terminations not supported when editing an existing Cable

View File

@ -1,10 +1,10 @@
from django.contrib.contenttypes.models import ContentType
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from drf_spectacular.utils import extend_schema_field from drf_spectacular.utils import extend_schema_field
from drf_spectacular.types import OpenApiTypes from drf_spectacular.types import OpenApiTypes
from rest_framework.fields import Field from rest_framework.fields import Field
from rest_framework.serializers import ValidationError from rest_framework.serializers import ValidationError
from core.models import ObjectType
from extras.choices import CustomFieldTypeChoices from extras.choices import CustomFieldTypeChoices
from extras.models import CustomField from extras.models import CustomField
from netbox.constants import NESTED_SERIALIZER_PREFIX from netbox.constants import NESTED_SERIALIZER_PREFIX
@ -25,8 +25,8 @@ class CustomFieldDefaultValues:
self.model = serializer_field.parent.Meta.model self.model = serializer_field.parent.Meta.model
# Retrieve the CustomFields for the parent model # Retrieve the CustomFields for the parent model
content_type = ContentType.objects.get_for_model(self.model) object_type = ObjectType.objects.get_for_model(self.model)
fields = CustomField.objects.filter(object_types=content_type) fields = CustomField.objects.filter(object_types=object_type)
# Populate the default value for each CustomField # Populate the default value for each CustomField
value = {} value = {}
@ -47,8 +47,8 @@ class CustomFieldsDataField(Field):
Cache CustomFields assigned to this model to avoid redundant database queries Cache CustomFields assigned to this model to avoid redundant database queries
""" """
if not hasattr(self, '_custom_fields'): if not hasattr(self, '_custom_fields'):
content_type = ContentType.objects.get_for_model(self.parent.Meta.model) object_type = ObjectType.objects.get_for_model(self.parent.Meta.model)
self._custom_fields = CustomField.objects.filter(object_types=content_type) self._custom_fields = CustomField.objects.filter(object_types=object_type)
return self._custom_fields return self._custom_fields
def to_representation(self, obj): def to_representation(self, obj):

View File

@ -257,7 +257,7 @@ def process_job_start_event_rules(sender, **kwargs):
""" """
Process event rules for jobs starting. Process event rules for jobs starting.
""" """
event_rules = EventRule.objects.filter(type_job_start=True, enabled=True, content_types=sender.object_type) event_rules = EventRule.objects.filter(type_job_start=True, enabled=True, object_types=sender.object_type)
username = sender.user.username if sender.user else None username = sender.user.username if sender.user else None
process_event_rules(event_rules, sender.object_type.model, EVENT_JOB_START, sender.data, username) process_event_rules(event_rules, sender.object_type.model, EVENT_JOB_START, sender.data, username)
@ -267,6 +267,6 @@ def process_job_end_event_rules(sender, **kwargs):
""" """
Process event rules for jobs terminating. Process event rules for jobs terminating.
""" """
event_rules = EventRule.objects.filter(type_job_end=True, enabled=True, content_types=sender.object_type) event_rules = EventRule.objects.filter(type_job_end=True, enabled=True, object_types=sender.object_type)
username = sender.user.username if sender.user else None username = sender.user.username if sender.user else None
process_event_rules(event_rules, sender.object_type.model, EVENT_JOB_END, sender.data, username) process_event_rules(event_rules, sender.object_type.model, EVENT_JOB_END, sender.data, username)

View File

@ -175,8 +175,6 @@ class WebhookTestCase(TestCase, BaseFilterSetTests):
@classmethod @classmethod
def setUpTestData(cls): def setUpTestData(cls):
content_types = ContentType.objects.filter(model__in=['region', 'site', 'rack', 'location', 'device'])
webhooks = ( webhooks = (
Webhook( Webhook(
name='Webhook 1', name='Webhook 1',
@ -355,7 +353,7 @@ class EventRuleTestCase(TestCase, BaseFilterSetTests):
def test_object_types(self): def test_object_types(self):
params = {'object_types': 'dcim.region'} params = {'object_types': 'dcim.region'}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
params = {'object_types_id': [ContentType.objects.get_for_model(Region).pk]} params = {'object_types_id': [ObjectType.objects.get_for_model(Region).pk]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
def test_action_type(self): def test_action_type(self):
@ -440,7 +438,7 @@ class CustomLinkTestCase(TestCase, BaseFilterSetTests):
def test_object_types(self): def test_object_types(self):
params = {'object_types': 'dcim.site'} params = {'object_types': 'dcim.site'}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
params = {'object_types_id': [ContentType.objects.get_for_model(Site).pk]} params = {'object_types_id': [ObjectType.objects.get_for_model(Site).pk]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
def test_weight(self): def test_weight(self):
@ -530,7 +528,7 @@ class SavedFilterTestCase(TestCase, BaseFilterSetTests):
def test_object_types(self): def test_object_types(self):
params = {'object_types': 'dcim.site'} params = {'object_types': 'dcim.site'}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
params = {'object_types_id': [ContentType.objects.get_for_model(Site).pk]} params = {'object_types_id': [ObjectType.objects.get_for_model(Site).pk]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
def test_user(self): def test_user(self):
@ -661,7 +659,7 @@ class ExportTemplateTestCase(TestCase, BaseFilterSetTests):
def test_object_types(self): def test_object_types(self):
params = {'object_types': 'dcim.site'} params = {'object_types': 'dcim.site'}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
params = {'object_types_id': [ContentType.objects.get_for_model(Site).pk]} params = {'object_types_id': [ObjectType.objects.get_for_model(Site).pk]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
def test_description(self): def test_description(self):
@ -1164,12 +1162,12 @@ class TagTestCase(TestCase, ChangeLoggedFilterSetTests):
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_object_types(self): def test_object_types(self):
params = {'for_object_type_id': [ContentType.objects.get_by_natural_key('dcim', 'site').pk]} params = {'for_object_type_id': [ObjectType.objects.get_by_natural_key('dcim', 'site').pk]}
self.assertEqual( self.assertEqual(
list(self.filterset(params, self.queryset).qs.values_list('name', flat=True)), list(self.filterset(params, self.queryset).qs.values_list('name', flat=True)),
['Tag 1', 'Tag 3'] ['Tag 1', 'Tag 3']
) )
params = {'for_object_type_id': [ContentType.objects.get_by_natural_key('circuits', 'provider').pk]} params = {'for_object_type_id': [ObjectType.objects.get_by_natural_key('circuits', 'provider').pk]}
self.assertEqual( self.assertEqual(
list(self.filterset(params, self.queryset).qs.values_list('name', flat=True)), list(self.filterset(params, self.queryset).qs.values_list('name', flat=True)),
['Tag 2', 'Tag 3'] ['Tag 2', 'Tag 3']

View File

@ -1,4 +1,3 @@
from django.contrib.contenttypes.models import ContentType
from django.test import TestCase from django.test import TestCase
from core.models import ObjectType from core.models import ObjectType
@ -63,14 +62,14 @@ class CustomFieldModelFormTest(TestCase):
cf_object = CustomField.objects.create( cf_object = CustomField.objects.create(
name='object', name='object',
type=CustomFieldTypeChoices.TYPE_OBJECT, type=CustomFieldTypeChoices.TYPE_OBJECT,
object_type=ContentType.objects.get_for_model(Site) object_type=ObjectType.objects.get_for_model(Site)
) )
cf_object.object_types.set([object_type]) cf_object.object_types.set([object_type])
cf_multiobject = CustomField.objects.create( cf_multiobject = CustomField.objects.create(
name='multiobject', name='multiobject',
type=CustomFieldTypeChoices.TYPE_MULTIOBJECT, type=CustomFieldTypeChoices.TYPE_MULTIOBJECT,
object_type=ContentType.objects.get_for_model(Site) object_type=ObjectType.objects.get_for_model(Site)
) )
cf_multiobject.object_types.set([object_type]) cf_multiobject.object_types.set([object_type])
@ -100,7 +99,7 @@ class SavedFilterFormTest(TestCase):
form = SavedFilterForm({ form = SavedFilterForm({
'name': 'test-sf', 'name': 'test-sf',
'slug': 'test-sf', 'slug': 'test-sf',
'object_types': [ContentType.objects.get_for_model(Site).pk], 'object_types': [ObjectType.objects.get_for_model(Site).pk],
'weight': 100, 'weight': 100,
'parameters': { 'parameters': {
"status": [ "status": [

View File

@ -1,9 +1,7 @@
from django.contrib.contenttypes.models import ContentType
from rest_framework import serializers from rest_framework import serializers
from rest_framework.fields import CreateOnlyDefault from rest_framework.fields import CreateOnlyDefault
from extras.api.customfields import CustomFieldsDataField, CustomFieldDefaultValues from extras.api.customfields import CustomFieldsDataField, CustomFieldDefaultValues
from extras.models import CustomField
from .nested import NestedTagSerializer from .nested import NestedTagSerializer
__all__ = ( __all__ = (

View File

@ -1,4 +1,3 @@
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.db import transaction from django.db import transaction
from django.http import Http404 from django.http import Http404
@ -41,8 +40,8 @@ class ExportTemplatesMixin:
""" """
def list(self, request, *args, **kwargs): def list(self, request, *args, **kwargs):
if 'export' in request.GET: if 'export' in request.GET:
content_type = ContentType.objects.get_for_model(self.get_serializer_class().Meta.model) object_type = ObjectType.objects.get_for_model(self.get_serializer_class().Meta.model)
et = ExportTemplate.objects.filter(content_types=content_type, name=request.GET['export']).first() et = ExportTemplate.objects.filter(object_types=object_type, name=request.GET['export']).first()
if et is None: if et is None:
raise Http404 raise Http404
queryset = self.filter_queryset(self.get_queryset()) queryset = self.filter_queryset(self.get_queryset())

View File

@ -3,6 +3,7 @@ from django.contrib.contenttypes.models import ContentType
from django.db.models import Q from django.db.models import Q
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from core.models import ObjectType
from extras.choices import * from extras.choices import *
from extras.models import CustomField, Tag from extras.models import CustomField, Tag
from utilities.forms import CSVModelForm from utilities.forms import CSVModelForm
@ -129,9 +130,9 @@ class NetBoxModelBulkEditForm(CustomFieldsMixin, forms.Form):
self.fields['pk'].queryset = self.model.objects.all() self.fields['pk'].queryset = self.model.objects.all()
# Restrict tag fields by model # Restrict tag fields by model
ct = ContentType.objects.get_for_model(self.model) object_type = ObjectType.objects.get_for_model(self.model)
self.fields['add_tags'].widget.add_query_param('for_object_type_id', ct.pk) self.fields['add_tags'].widget.add_query_param('for_object_type_id', object_type.pk)
self.fields['remove_tags'].widget.add_query_param('for_object_type_id', ct.pk) self.fields['remove_tags'].widget.add_query_param('for_object_type_id', object_type.pk)
self._extend_nullable_fields() self._extend_nullable_fields()
@ -169,9 +170,9 @@ class NetBoxModelFilterSetForm(CustomFieldsMixin, SavedFiltersMixin, forms.Form)
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
# Limit saved filters to those applicable to the form's model # Limit saved filters to those applicable to the form's model
content_type = ContentType.objects.get_for_model(self.model) object_type = ObjectType.objects.get_for_model(self.model)
self.fields['filter_id'].widget.add_query_params({ self.fields['filter_id'].widget.add_query_params({
'content_type_id': content_type.pk, 'object_types_id': object_type.pk,
}) })
def _get_custom_fields(self, content_type): def _get_custom_fields(self, content_type):

View File

@ -1,5 +1,4 @@
from django import forms from django import forms
from django.contrib.contenttypes.models import ContentType
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from core.models import ObjectType from core.models import ObjectType
@ -86,6 +85,6 @@ class TagsMixin(forms.Form):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
# Limit tags to those applicable to the object type # Limit tags to those applicable to the object type
content_type = ContentType.objects.get_for_model(self._meta.model) object_type = ObjectType.objects.get_for_model(self._meta.model)
if content_type and hasattr(self.fields['tags'].widget, 'add_query_param'): if object_type and hasattr(self.fields['tags'].widget, 'add_query_param'):
self.fields['tags'].widget.add_query_param('for_object_type_id', content_type.pk) self.fields['tags'].widget.add_query_param('for_object_type_id', object_type.pk)

View File

@ -131,11 +131,11 @@ class CachedValueSearchBackend(SearchBackend):
) )
)[:MAX_RESULTS] )[:MAX_RESULTS]
# Gather all ContentTypes present in the search results (used for prefetching related # Gather all ObjectTypes present in the search results (used for prefetching related
# objects). This must be done before generating the final results list, which returns # objects). This must be done before generating the final results list, which returns
# a RawQuerySet. # a RawQuerySet.
content_type_ids = set(queryset.values_list('object_type', flat=True)) object_type_ids = set(queryset.values_list('object_type', flat=True))
object_types = ObjectType.objects.filter(pk__in=content_type_ids) object_types = ObjectType.objects.filter(pk__in=object_type_ids)
# Construct a Prefetch to pre-fetch only those related objects for which the # Construct a Prefetch to pre-fetch only those related objects for which the
# user has permission to view. # user has permission to view.
@ -152,11 +152,11 @@ class CachedValueSearchBackend(SearchBackend):
params params
) )
# Iterate through each ContentType represented in the search results and prefetch any # Iterate through each ObjectType represented in the search results and prefetch any
# related objects necessary to render the prescribed display attributes (display_attrs). # related objects necessary to render the prescribed display attributes (display_attrs).
for ct in object_types: for object_type in object_types:
model = ct.model_class() model = object_type.model_class()
indexer = registry['search'].get(content_type_identifier(ct)) indexer = registry['search'].get(content_type_identifier(object_type))
if not (display_attrs := getattr(indexer, 'display_attrs', None)): if not (display_attrs := getattr(indexer, 'display_attrs', None)):
continue continue
@ -170,7 +170,7 @@ class CachedValueSearchBackend(SearchBackend):
# Compile a list of all CachedValues referencing this object type, and prefetch # Compile a list of all CachedValues referencing this object type, and prefetch
# any related objects # any related objects
if prefetch_fields: if prefetch_fields:
objects = [r for r in results if r.object_type == ct] objects = [r for r in results if r.object_type == object_type]
prefetch_related_objects(objects, *prefetch_fields) prefetch_related_objects(objects, *prefetch_fields)
# Omit any results pertaining to an object the user does not have permission to view # Omit any results pertaining to an object the user does not have permission to view

View File

@ -4,7 +4,6 @@ from copy import deepcopy
from django.contrib import messages from django.contrib import messages
from django.contrib.contenttypes.fields import GenericRel from django.contrib.contenttypes.fields import GenericRel
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import FieldDoesNotExist, ObjectDoesNotExist, ValidationError from django.core.exceptions import FieldDoesNotExist, ObjectDoesNotExist, ValidationError
from django.db import transaction, IntegrityError from django.db import transaction, IntegrityError
from django.db.models import ManyToManyField, ProtectedError, RestrictedError from django.db.models import ManyToManyField, ProtectedError, RestrictedError
@ -17,6 +16,7 @@ from django.utils.safestring import mark_safe
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from django_tables2.export import TableExport from django_tables2.export import TableExport
from core.models import ObjectType
from extras.models import ExportTemplate from extras.models import ExportTemplate
from extras.signals import clear_events from extras.signals import clear_events
from utilities.error_handlers import handle_protectederror from utilities.error_handlers import handle_protectederror
@ -124,7 +124,7 @@ class ObjectListView(BaseMultiObjectView, ActionsMixin, TableMixin):
request: The current request request: The current request
""" """
model = self.queryset.model model = self.queryset.model
content_type = ContentType.objects.get_for_model(model) object_type = ObjectType.objects.get_for_model(model)
if self.filterset: if self.filterset:
self.queryset = self.filterset(request.GET, self.queryset, request=request).qs self.queryset = self.filterset(request.GET, self.queryset, request=request).qs
@ -143,7 +143,7 @@ class ObjectListView(BaseMultiObjectView, ActionsMixin, TableMixin):
# Render an ExportTemplate # Render an ExportTemplate
elif request.GET['export']: elif request.GET['export']:
template = get_object_or_404(ExportTemplate, content_types=content_type, name=request.GET['export']) template = get_object_or_404(ExportTemplate, object_types=object_type, name=request.GET['export'])
return self.export_template(template, request) return self.export_template(template, request)
# Check for YAML export support on the model # Check for YAML export support on the model

View File

@ -1,6 +1,6 @@
from django.contrib.contenttypes.models import ContentType
from django.test import TestCase from django.test import TestCase
from core.models import ObjectType
from dcim.models import Manufacturer, Site from dcim.models import Manufacturer, Site
from tenancy.filtersets import * from tenancy.filtersets import *
from tenancy.models import * from tenancy.models import *
@ -296,7 +296,7 @@ class ContactAssignmentTestCase(TestCase, ChangeLoggedFilterSetTests):
ContactAssignment.objects.bulk_create(assignments) ContactAssignment.objects.bulk_create(assignments)
def test_object_type(self): def test_object_type(self):
params = {'object_type_id': ContentType.objects.get_by_natural_key('dcim', 'site')} params = {'object_type_id': ObjectType.objects.get_by_natural_key('dcim', 'site')}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3) self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3)
def test_contact(self): def test_contact(self):

View File

@ -1,9 +1,9 @@
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.contrib.contenttypes.models import ContentType
from drf_spectacular.utils import extend_schema_field from drf_spectacular.utils import extend_schema_field
from drf_spectacular.types import OpenApiTypes from drf_spectacular.types import OpenApiTypes
from rest_framework import serializers from rest_framework import serializers
from core.models import ObjectType
from netbox.api.fields import ContentTypeField from netbox.api.fields import ContentTypeField
from netbox.api.serializers import WritableNestedSerializer from netbox.api.serializers import WritableNestedSerializer
from users.models import Group, ObjectPermission, Token from users.models import Group, ObjectPermission, Token
@ -49,7 +49,7 @@ class NestedTokenSerializer(WritableNestedSerializer):
class NestedObjectPermissionSerializer(WritableNestedSerializer): class NestedObjectPermissionSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='users-api:objectpermission-detail') url = serializers.HyperlinkedIdentityField(view_name='users-api:objectpermission-detail')
object_types = ContentTypeField( object_types = ContentTypeField(
queryset=ContentType.objects.all(), queryset=ObjectType.objects.all(),
many=True many=True
) )
groups = serializers.SerializerMethodField(read_only=True) groups = serializers.SerializerMethodField(read_only=True)

View File

@ -1,7 +1,6 @@
import datetime import datetime
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.contrib.contenttypes.models import ContentType
from django.test import TestCase from django.test import TestCase
from django.utils.timezone import make_aware from django.utils.timezone import make_aware
@ -199,7 +198,7 @@ class ObjectPermissionTestCase(TestCase, BaseFilterSetTests):
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_object_types(self): def test_object_types(self):
object_types = ContentType.objects.filter(model__in=['site', 'rack']) object_types = ObjectType.objects.filter(model__in=['site', 'rack'])
params = {'object_types': [object_types[0].pk, object_types[1].pk]} params = {'object_types': [object_types[0].pk, object_types[1].pk]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)

View File

@ -1,5 +1,4 @@
from django.contrib.contenttypes.models import ContentType from core.models import ObjectType
from users.models import * from users.models import *
from utilities.testing import ViewTestCases, create_test_user from utilities.testing import ViewTestCases, create_test_user
@ -115,7 +114,7 @@ class ObjectPermissionTestCase(
@classmethod @classmethod
def setUpTestData(cls): def setUpTestData(cls):
ct = ContentType.objects.get_by_natural_key('dcim', 'site') object_type = ObjectType.objects.get_by_natural_key('dcim', 'site')
permissions = ( permissions = (
ObjectPermission(name='Permission 1', actions=['view', 'add', 'delete']), ObjectPermission(name='Permission 1', actions=['view', 'add', 'delete']),
@ -127,7 +126,7 @@ class ObjectPermissionTestCase(
cls.form_data = { cls.form_data = {
'name': 'Permission X', 'name': 'Permission X',
'description': 'A new permission', 'description': 'A new permission',
'object_types': [ct.pk], 'object_types': [object_type.pk],
'actions': 'view,edit,delete', 'actions': 'view,edit,delete',
} }

View File

@ -1,16 +1,16 @@
import datetime import datetime
import json import json
from urllib.parse import quote
from typing import Dict, Any from typing import Dict, Any
from urllib.parse import quote
from django import template from django import template
from django.conf import settings from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.template.defaultfilters import date from django.template.defaultfilters import date
from django.urls import NoReverseMatch, reverse from django.urls import NoReverseMatch, reverse
from django.utils import timezone from django.utils import timezone
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from core.models import ObjectType
from utilities.forms import get_selected_values, TableConfigForm from utilities.forms import get_selected_values, TableConfigForm
from utilities.utils import get_viewname from utilities.utils import get_viewname
@ -322,10 +322,10 @@ def applied_filters(context, model, form, query_params):
save_link = None save_link = None
if user.has_perm('extras.add_savedfilter') and 'filter_id' not in context['request'].GET: if user.has_perm('extras.add_savedfilter') and 'filter_id' not in context['request'].GET:
content_type = ContentType.objects.get_for_model(model).pk object_type = ObjectType.objects.get_for_model(model).pk
parameters = json.dumps(dict(context['request'].GET.lists())) parameters = json.dumps(dict(context['request'].GET.lists()))
url = reverse('extras:savedfilter_add') url = reverse('extras:savedfilter_add')
save_link = f"{url}?content_types={content_type}&parameters={quote(parameters)}" save_link = f"{url}?object_types={object_type}&parameters={quote(parameters)}"
return { return {
'applied_filters': applied_filters, 'applied_filters': applied_filters,

View File

@ -1,11 +1,9 @@
from django.contrib.contenttypes.models import ContentType
from django.test import override_settings from django.test import override_settings
from django.urls import reverse from django.urls import reverse
from dcim.models import * from dcim.models import *
from users.models import ObjectPermission
from utilities.testing.base import TestCase from utilities.testing.base import TestCase
from utilities.testing.utils import create_test_device, create_test_user from utilities.testing.utils import create_test_device
class CountersTest(TestCase): class CountersTest(TestCase):