diff --git a/netbox/core/models/data.py b/netbox/core/models/data.py index 78f05e462..cf40c0bd5 100644 --- a/netbox/core/models/data.py +++ b/netbox/core/models/data.py @@ -6,7 +6,6 @@ from urllib.parse import urlparse from django.conf import settings from django.contrib.contenttypes.fields import GenericForeignKey -from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ValidationError from django.core.validators import RegexValidator from django.db import models @@ -368,7 +367,7 @@ class AutoSyncRecord(models.Model): related_name='+' ) object_type = models.ForeignKey( - to=ContentType, + to='contenttypes.ContentType', on_delete=models.CASCADE, related_name='+' ) diff --git a/netbox/core/models/jobs.py b/netbox/core/models/jobs.py index 93c5ba67f..f2151da92 100644 --- a/netbox/core/models/jobs.py +++ b/netbox/core/models/jobs.py @@ -3,7 +3,6 @@ import uuid import django_rq from django.conf import settings from django.contrib.contenttypes.fields import GenericForeignKey -from django.contrib.contenttypes.models import ContentType from django.core.validators import MinValueValidator from django.db import models from django.urls import reverse @@ -11,6 +10,7 @@ from django.utils import timezone from django.utils.translation import gettext as _ from core.choices import JobStatusChoices +from core.models import ContentType from extras.constants import EVENT_JOB_END, EVENT_JOB_START from netbox.config import get_config from netbox.constants import RQ_QUEUE_DEFAULT diff --git a/netbox/dcim/models/cables.py b/netbox/dcim/models/cables.py index d248b5cad..bc9ca529d 100644 --- a/netbox/dcim/models/cables.py +++ b/netbox/dcim/models/cables.py @@ -2,7 +2,6 @@ import itertools from collections import defaultdict from django.contrib.contenttypes.fields import GenericForeignKey -from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ValidationError from django.db import models from django.db.models import Sum @@ -10,12 +9,12 @@ from django.dispatch import Signal from django.urls import reverse from django.utils.translation import gettext_lazy as _ +from core.models import ContentType from dcim.choices import * from dcim.constants import * from dcim.fields import PathField from dcim.utils import decompile_path_node, object_to_path_node from netbox.models import ChangeLoggedModel, PrimaryModel - from utilities.fields import ColorField from utilities.querysets import RestrictedQuerySet from utilities.utils import to_meters @@ -247,7 +246,7 @@ class CableTermination(ChangeLoggedModel): verbose_name=_('end') ) termination_type = models.ForeignKey( - to=ContentType, + to='contenttypes.ContentType', limit_choices_to=CABLE_TERMINATION_MODELS, on_delete=models.PROTECT, related_name='+' diff --git a/netbox/dcim/models/device_component_templates.py b/netbox/dcim/models/device_component_templates.py index 5110835f4..fb3d6333e 100644 --- a/netbox/dcim/models/device_component_templates.py +++ b/netbox/dcim/models/device_component_templates.py @@ -1,5 +1,4 @@ from django.contrib.contenttypes.fields import GenericForeignKey -from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ValidationError from django.core.validators import MaxValueValidator, MinValueValidator from django.db import models @@ -709,7 +708,7 @@ class InventoryItemTemplate(MPTTModel, ComponentTemplateModel): db_index=True ) component_type = models.ForeignKey( - to=ContentType, + to='contenttypes.ContentType', limit_choices_to=MODULAR_COMPONENT_TEMPLATE_MODELS, on_delete=models.PROTECT, related_name='+', diff --git a/netbox/dcim/models/device_components.py b/netbox/dcim/models/device_components.py index 94568459e..c24ed4d86 100644 --- a/netbox/dcim/models/device_components.py +++ b/netbox/dcim/models/device_components.py @@ -1,7 +1,6 @@ from functools import cached_property from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation -from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ValidationError from django.core.validators import MaxValueValidator, MinValueValidator from django.db import models @@ -1181,7 +1180,7 @@ class InventoryItem(MPTTModel, ComponentModel, TrackingModelMixin): db_index=True ) component_type = models.ForeignKey( - to=ContentType, + to='contenttypes.ContentType', limit_choices_to=MODULAR_COMPONENT_MODELS, on_delete=models.PROTECT, related_name='+', diff --git a/netbox/extras/models/change_logging.py b/netbox/extras/models/change_logging.py index ac9c60998..072187e6f 100644 --- a/netbox/extras/models/change_logging.py +++ b/netbox/extras/models/change_logging.py @@ -1,6 +1,5 @@ from django.conf import settings from django.contrib.contenttypes.fields import GenericForeignKey -from django.contrib.contenttypes.models import ContentType from django.db import models from django.urls import reverse from django.utils.translation import gettext_lazy as _ @@ -48,7 +47,7 @@ class ObjectChange(models.Model): choices=ObjectChangeActionChoices ) changed_object_type = models.ForeignKey( - to=ContentType, + to='contenttypes.ContentType', on_delete=models.PROTECT, related_name='+' ) @@ -58,7 +57,7 @@ class ObjectChange(models.Model): fk_field='changed_object_id' ) related_object_type = models.ForeignKey( - to=ContentType, + to='contenttypes.ContentType', on_delete=models.PROTECT, related_name='+', blank=True, diff --git a/netbox/extras/models/customfields.py b/netbox/extras/models/customfields.py index 48fe3bb6a..939e8b73b 100644 --- a/netbox/extras/models/customfields.py +++ b/netbox/extras/models/customfields.py @@ -5,7 +5,6 @@ from datetime import datetime, date import django_filters from django import forms from django.conf import settings -from django.contrib.contenttypes.models import ContentType from django.contrib.postgres.fields import ArrayField from django.core.validators import RegexValidator, ValidationError from django.db import models @@ -13,6 +12,7 @@ from django.urls import reverse from django.utils.safestring import mark_safe from django.utils.translation import gettext_lazy as _ +from core.models import ContentType from extras.choices import * from extras.data import CHOICE_SETS from netbox.models import ChangeLoggedModel diff --git a/netbox/extras/models/models.py b/netbox/extras/models/models.py index 5791ae870..1de8e4def 100644 --- a/netbox/extras/models/models.py +++ b/netbox/extras/models/models.py @@ -234,7 +234,7 @@ class CustomLink(CloningMixin, ExportTemplatesMixin, ChangeLoggedModel): code to be rendered with an object as context. """ content_types = models.ManyToManyField( - to=ContentType, + to='contenttypes.ContentType', related_name='custom_links', help_text=_('The object type(s) to which this link applies.') ) @@ -330,7 +330,7 @@ class CustomLink(CloningMixin, ExportTemplatesMixin, ChangeLoggedModel): class ExportTemplate(SyncedDataMixin, CloningMixin, ExportTemplatesMixin, ChangeLoggedModel): content_types = models.ManyToManyField( - to=ContentType, + to='contenttypes.ContentType', related_name='export_templates', help_text=_('The object type(s) to which this template applies.') ) @@ -439,7 +439,7 @@ class SavedFilter(CloningMixin, ExportTemplatesMixin, ChangeLoggedModel): A set of predefined keyword parameters that can be reused to filter for specific objects. """ content_types = models.ManyToManyField( - to=ContentType, + to='contenttypes.ContentType', related_name='saved_filters', help_text=_('The object type(s) to which this filter applies.') ) @@ -519,7 +519,7 @@ class ImageAttachment(ChangeLoggedModel): An uploaded image which is associated with an object. """ content_type = models.ForeignKey( - to=ContentType, + to='contenttypes.ContentType', on_delete=models.CASCADE ) object_id = models.PositiveBigIntegerField() @@ -604,7 +604,7 @@ class JournalEntry(CustomFieldsMixin, CustomLinksMixin, TagsMixin, ExportTemplat might record a new journal entry when a device undergoes maintenance, or when a prefix is expanded. """ assigned_object_type = models.ForeignKey( - to=ContentType, + to='contenttypes.ContentType', on_delete=models.CASCADE ) assigned_object_id = models.PositiveBigIntegerField() @@ -663,7 +663,7 @@ class Bookmark(models.Model): auto_now_add=True ) object_type = models.ForeignKey( - to=ContentType, + to='contenttypes.ContentType', on_delete=models.PROTECT ) object_id = models.PositiveBigIntegerField() diff --git a/netbox/extras/models/search.py b/netbox/extras/models/search.py index b3327d510..04a88e69f 100644 --- a/netbox/extras/models/search.py +++ b/netbox/extras/models/search.py @@ -1,6 +1,5 @@ import uuid -from django.contrib.contenttypes.models import ContentType from django.db import models from django.utils.translation import gettext_lazy as _ @@ -24,7 +23,7 @@ class CachedValue(models.Model): editable=False ) object_type = models.ForeignKey( - to=ContentType, + to='contenttypes.ContentType', on_delete=models.CASCADE, related_name='+' ) diff --git a/netbox/extras/models/staging.py b/netbox/extras/models/staging.py index b0df9e26e..2e848a817 100644 --- a/netbox/extras/models/staging.py +++ b/netbox/extras/models/staging.py @@ -2,7 +2,6 @@ import logging from django.contrib.auth import get_user_model from django.contrib.contenttypes.fields import GenericForeignKey -from django.contrib.contenttypes.models import ContentType from django.db import models, transaction from django.utils.translation import gettext_lazy as _ @@ -71,7 +70,7 @@ class StagedChange(ChangeLoggedModel): choices=ChangeActionChoices ) object_type = models.ForeignKey( - to=ContentType, + to='contenttypes.ContentType', on_delete=models.CASCADE, related_name='+' ) diff --git a/netbox/ipam/models/fhrp.py b/netbox/ipam/models/fhrp.py index 5d355102f..1e4e7dac3 100644 --- a/netbox/ipam/models/fhrp.py +++ b/netbox/ipam/models/fhrp.py @@ -1,13 +1,12 @@ from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation -from django.contrib.contenttypes.models import ContentType from django.core.validators import MaxValueValidator, MinValueValidator from django.db import models from django.urls import reverse from django.utils.translation import gettext_lazy as _ -from netbox.models import ChangeLoggedModel, PrimaryModel from ipam.choices import * from ipam.constants import * +from netbox.models import ChangeLoggedModel, PrimaryModel __all__ = ( 'FHRPGroup', @@ -78,7 +77,7 @@ class FHRPGroup(PrimaryModel): class FHRPGroupAssignment(ChangeLoggedModel): interface_type = models.ForeignKey( - to=ContentType, + to='contenttypes.ContentType', on_delete=models.CASCADE ) interface_id = models.PositiveBigIntegerField() diff --git a/netbox/ipam/models/ip.py b/netbox/ipam/models/ip.py index 934cb98c7..7dc0ac445 100644 --- a/netbox/ipam/models/ip.py +++ b/netbox/ipam/models/ip.py @@ -1,6 +1,5 @@ import netaddr from django.contrib.contenttypes.fields import GenericForeignKey -from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ValidationError from django.db import models from django.db.models import F @@ -9,6 +8,7 @@ from django.urls import reverse from django.utils.functional import cached_property from django.utils.translation import gettext_lazy as _ +from core.models import ContentType from ipam.choices import * from ipam.constants import * from ipam.fields import IPNetworkField, IPAddressField @@ -740,7 +740,7 @@ class IPAddress(PrimaryModel): help_text=_('The functional role of this IP') ) assigned_object_type = models.ForeignKey( - to=ContentType, + to='contenttypes.ContentType', limit_choices_to=IPADDRESS_ASSIGNMENT_MODELS, on_delete=models.PROTECT, related_name='+', diff --git a/netbox/ipam/models/l2vpn.py b/netbox/ipam/models/l2vpn.py index 3072fc6c3..a2742a8f3 100644 --- a/netbox/ipam/models/l2vpn.py +++ b/netbox/ipam/models/l2vpn.py @@ -1,11 +1,11 @@ from django.contrib.contenttypes.fields import GenericForeignKey -from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ValidationError from django.db import models from django.urls import reverse from django.utils.functional import cached_property from django.utils.translation import gettext_lazy as _ +from core.models import ContentType from ipam.choices import L2VPNTypeChoices from ipam.constants import L2VPN_ASSIGNMENT_MODELS from netbox.models import NetBoxModel, PrimaryModel @@ -86,7 +86,7 @@ class L2VPNTermination(NetBoxModel): related_name='terminations' ) assigned_object_type = models.ForeignKey( - to=ContentType, + to='contenttypes.ContentType', limit_choices_to=L2VPN_ASSIGNMENT_MODELS, on_delete=models.PROTECT, related_name='+' diff --git a/netbox/ipam/models/vlans.py b/netbox/ipam/models/vlans.py index 675d03ee5..b6aed5398 100644 --- a/netbox/ipam/models/vlans.py +++ b/netbox/ipam/models/vlans.py @@ -1,5 +1,4 @@ from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation -from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ValidationError from django.core.validators import MaxValueValidator, MinValueValidator from django.db import models @@ -32,7 +31,7 @@ class VLANGroup(OrganizationalModel): max_length=100 ) scope_type = models.ForeignKey( - to=ContentType, + to='contenttypes.ContentType', on_delete=models.CASCADE, limit_choices_to=Q(model__in=VLANGROUP_SCOPE_TYPES), blank=True, diff --git a/netbox/netbox/models/features.py b/netbox/netbox/models/features.py index cce265efc..11307b4f8 100644 --- a/netbox/netbox/models/features.py +++ b/netbox/netbox/models/features.py @@ -3,7 +3,6 @@ from collections import defaultdict from functools import cached_property from django.contrib.contenttypes.fields import GenericRelation -from django.contrib.contenttypes.models import ContentType from django.core.validators import ValidationError from django.db import models from django.db.models.signals import class_prepared @@ -13,6 +12,7 @@ from django.utils.translation import gettext_lazy as _ from taggit.managers import TaggableManager from core.choices import JobStatusChoices +from core.models import ContentType from extras.choices import CustomFieldVisibilityChoices, ObjectChangeActionChoices from extras.utils import is_taggable, register_features from netbox.registry import registry diff --git a/netbox/tenancy/models/contacts.py b/netbox/tenancy/models/contacts.py index e8327248d..306a1cad9 100644 --- a/netbox/tenancy/models/contacts.py +++ b/netbox/tenancy/models/contacts.py @@ -1,5 +1,4 @@ from django.contrib.contenttypes.fields import GenericForeignKey -from django.contrib.contenttypes.models import ContentType from django.db import models from django.urls import reverse from django.utils.translation import gettext_lazy as _ @@ -111,7 +110,7 @@ class Contact(PrimaryModel): class ContactAssignment(ChangeLoggedModel, TagsMixin): content_type = models.ForeignKey( - to=ContentType, + to='contenttypes.ContentType', on_delete=models.CASCADE ) object_id = models.PositiveBigIntegerField() diff --git a/netbox/users/models.py b/netbox/users/models.py index 2a345653d..d77d4932c 100644 --- a/netbox/users/models.py +++ b/netbox/users/models.py @@ -3,7 +3,6 @@ import os from django.conf import settings from django.contrib.auth.models import Group, GroupManager, User, UserManager -from django.contrib.contenttypes.models import ContentType from django.contrib.postgres.fields import ArrayField from django.core.exceptions import ValidationError from django.core.validators import MinLengthValidator @@ -15,6 +14,7 @@ from django.utils import timezone from django.utils.translation import gettext_lazy as _ from netaddr import IPNetwork +from core.models import ContentType from ipam.fields import IPNetworkField from netbox.config import get_config from utilities.querysets import RestrictedQuerySet @@ -353,7 +353,7 @@ class ObjectPermission(models.Model): default=True ) object_types = models.ManyToManyField( - to=ContentType, + to='contenttypes.ContentType', limit_choices_to=OBJECTPERMISSION_OBJECT_TYPES, related_name='object_permissions' )