Explorar o código

Introduce ImageAttachmentsMixin

Jeremy Stretch %!s(int64=2) %!d(string=hai) anos
pai
achega
14e23c3d00

+ 3 - 7
netbox/circuits/models/circuits.py

@@ -6,9 +6,8 @@ from django.utils.translation import gettext_lazy as _
 
 
 from circuits.choices import *
 from circuits.choices import *
 from dcim.models import CabledObjectModel
 from dcim.models import CabledObjectModel
-from netbox.models import (
-    ChangeLoggedModel, CustomFieldsMixin, CustomLinksMixin, OrganizationalModel, PrimaryModel, TagsMixin,
-)
+from netbox.models import ChangeLoggedModel, OrganizationalModel, PrimaryModel
+from netbox.models.features import CustomFieldsMixin, CustomLinksMixin, ImageAttachmentsMixin, TagsMixin
 
 
 __all__ = (
 __all__ = (
     'Circuit',
     'Circuit',
@@ -31,7 +30,7 @@ class CircuitType(OrganizationalModel):
         verbose_name_plural = _('circuit types')
         verbose_name_plural = _('circuit types')
 
 
 
 
-class Circuit(PrimaryModel):
+class Circuit(ImageAttachmentsMixin, PrimaryModel):
     """
     """
     A communications circuit connects two points. Each Circuit belongs to a Provider; Providers may have multiple
     A communications circuit connects two points. Each Circuit belongs to a Provider; Providers may have multiple
     circuits. Each circuit is also assigned a CircuitType and a Site, and may optionally be assigned to a particular
     circuits. Each circuit is also assigned a CircuitType and a Site, and may optionally be assigned to a particular
@@ -93,9 +92,6 @@ class Circuit(PrimaryModel):
     contacts = GenericRelation(
     contacts = GenericRelation(
         to='tenancy.ContactAssignment'
         to='tenancy.ContactAssignment'
     )
     )
-    images = GenericRelation(
-        to='extras.ImageAttachment'
-    )
 
 
     # Cache associated CircuitTerminations
     # Cache associated CircuitTerminations
     termination_a = models.ForeignKey(
     termination_a = models.ForeignKey(

+ 4 - 15
netbox/dcim/models/devices.py

@@ -20,6 +20,7 @@ from extras.models import ConfigContextModel
 from extras.querysets import ConfigContextModelQuerySet
 from extras.querysets import ConfigContextModelQuerySet
 from netbox.config import ConfigItem
 from netbox.config import ConfigItem
 from netbox.models import OrganizationalModel, PrimaryModel
 from netbox.models import OrganizationalModel, PrimaryModel
+from netbox.models.features import ImageAttachmentsMixin
 from utilities.choices import ColorChoices
 from utilities.choices import ColorChoices
 from utilities.fields import ColorField, CounterCacheField, NaturalOrderingField
 from utilities.fields import ColorField, CounterCacheField, NaturalOrderingField
 from utilities.tracking import TrackingModelMixin
 from utilities.tracking import TrackingModelMixin
@@ -62,7 +63,7 @@ class Manufacturer(OrganizationalModel):
         return reverse('dcim:manufacturer', args=[self.pk])
         return reverse('dcim:manufacturer', args=[self.pk])
 
 
 
 
-class DeviceType(PrimaryModel, WeightMixin):
+class DeviceType(ImageAttachmentsMixin, PrimaryModel, WeightMixin):
     """
     """
     A DeviceType represents a particular make (Manufacturer) and model of device. It specifies rack height and depth, as
     A DeviceType represents a particular make (Manufacturer) and model of device. It specifies rack height and depth, as
     well as high-level functional role(s).
     well as high-level functional role(s).
@@ -180,10 +181,6 @@ class DeviceType(PrimaryModel, WeightMixin):
         to_field='device_type'
         to_field='device_type'
     )
     )
 
 
-    images = GenericRelation(
-        to='extras.ImageAttachment'
-    )
-
     clone_fields = (
     clone_fields = (
         'manufacturer', 'default_platform', 'u_height', 'is_full_depth', 'subdevice_role', 'airflow', 'weight',
         'manufacturer', 'default_platform', 'u_height', 'is_full_depth', 'subdevice_role', 'airflow', 'weight',
         'weight_unit',
         'weight_unit',
@@ -366,7 +363,7 @@ class DeviceType(PrimaryModel, WeightMixin):
         return self.subdevice_role == SubdeviceRoleChoices.ROLE_CHILD
         return self.subdevice_role == SubdeviceRoleChoices.ROLE_CHILD
 
 
 
 
-class ModuleType(PrimaryModel, WeightMixin):
+class ModuleType(ImageAttachmentsMixin, PrimaryModel, WeightMixin):
     """
     """
     A ModuleType represents a hardware element that can be installed within a device and which houses additional
     A ModuleType represents a hardware element that can be installed within a device and which houses additional
     components; for example, a line card within a chassis-based switch such as the Cisco Catalyst 6500. Like a
     components; for example, a line card within a chassis-based switch such as the Cisco Catalyst 6500. Like a
@@ -389,11 +386,6 @@ class ModuleType(PrimaryModel, WeightMixin):
         help_text=_('Discrete part number (optional)')
         help_text=_('Discrete part number (optional)')
     )
     )
 
 
-    # Generic relations
-    images = GenericRelation(
-        to='extras.ImageAttachment'
-    )
-
     clone_fields = ('manufacturer', 'weight', 'weight_unit',)
     clone_fields = ('manufacturer', 'weight', 'weight_unit',)
     prerequisite_models = (
     prerequisite_models = (
         'dcim.Manufacturer',
         'dcim.Manufacturer',
@@ -539,7 +531,7 @@ def update_interface_bridges(device, interface_templates, module=None):
             interface.save()
             interface.save()
 
 
 
 
-class Device(PrimaryModel, ConfigContextModel, TrackingModelMixin):
+class Device(ImageAttachmentsMixin, PrimaryModel, ConfigContextModel, TrackingModelMixin):
     """
     """
     A Device represents a piece of physical hardware mounted within a Rack. Each Device is assigned a DeviceType,
     A Device represents a piece of physical hardware mounted within a Rack. Each Device is assigned a DeviceType,
     DeviceRole, and (optionally) a Platform. Device names are not required, however if one is set it must be unique.
     DeviceRole, and (optionally) a Platform. Device names are not required, however if one is set it must be unique.
@@ -770,9 +762,6 @@ class Device(PrimaryModel, ConfigContextModel, TrackingModelMixin):
     contacts = GenericRelation(
     contacts = GenericRelation(
         to='tenancy.ContactAssignment'
         to='tenancy.ContactAssignment'
     )
     )
-    images = GenericRelation(
-        to='extras.ImageAttachment'
-    )
 
 
     objects = ConfigContextModelQuerySet.as_manager()
     objects = ConfigContextModelQuerySet.as_manager()
 
 

+ 2 - 4
netbox/dcim/models/power.py

@@ -8,6 +8,7 @@ from django.utils.translation import gettext_lazy as _
 from dcim.choices import *
 from dcim.choices import *
 from netbox.config import ConfigItem
 from netbox.config import ConfigItem
 from netbox.models import PrimaryModel
 from netbox.models import PrimaryModel
+from netbox.models.features import ImageAttachmentsMixin
 from utilities.validators import ExclusionValidator
 from utilities.validators import ExclusionValidator
 from .device_components import CabledObjectModel, PathEndpoint
 from .device_components import CabledObjectModel, PathEndpoint
 
 
@@ -21,7 +22,7 @@ __all__ = (
 # Power
 # Power
 #
 #
 
 
-class PowerPanel(PrimaryModel):
+class PowerPanel(ImageAttachmentsMixin, PrimaryModel):
     """
     """
     A distribution point for electrical power; e.g. a data center RPP.
     A distribution point for electrical power; e.g. a data center RPP.
     """
     """
@@ -44,9 +45,6 @@ class PowerPanel(PrimaryModel):
     contacts = GenericRelation(
     contacts = GenericRelation(
         to='tenancy.ContactAssignment'
         to='tenancy.ContactAssignment'
     )
     )
-    images = GenericRelation(
-        to='extras.ImageAttachment'
-    )
 
 
     prerequisite_models = (
     prerequisite_models = (
         'dcim.Site',
         'dcim.Site',

+ 2 - 4
netbox/dcim/models/racks.py

@@ -15,6 +15,7 @@ from dcim.choices import *
 from dcim.constants import *
 from dcim.constants import *
 from dcim.svg import RackElevationSVG
 from dcim.svg import RackElevationSVG
 from netbox.models import OrganizationalModel, PrimaryModel
 from netbox.models import OrganizationalModel, PrimaryModel
+from netbox.models.features import ImageAttachmentsMixin
 from utilities.choices import ColorChoices
 from utilities.choices import ColorChoices
 from utilities.fields import ColorField, NaturalOrderingField
 from utilities.fields import ColorField, NaturalOrderingField
 from utilities.utils import array_to_string, drange, to_grams
 from utilities.utils import array_to_string, drange, to_grams
@@ -52,7 +53,7 @@ class RackRole(OrganizationalModel):
         return reverse('dcim:rackrole', args=[self.pk])
         return reverse('dcim:rackrole', args=[self.pk])
 
 
 
 
-class Rack(PrimaryModel, WeightMixin):
+class Rack(ImageAttachmentsMixin, PrimaryModel, WeightMixin):
     """
     """
     Devices are housed within Racks. Each rack has a defined height measured in rack units, and a front and rear face.
     Devices are housed within Racks. Each rack has a defined height measured in rack units, and a front and rear face.
     Each Rack is assigned to a Site and (optionally) a Location.
     Each Rack is assigned to a Site and (optionally) a Location.
@@ -196,9 +197,6 @@ class Rack(PrimaryModel, WeightMixin):
     contacts = GenericRelation(
     contacts = GenericRelation(
         to='tenancy.ContactAssignment'
         to='tenancy.ContactAssignment'
     )
     )
-    images = GenericRelation(
-        to='extras.ImageAttachment'
-    )
 
 
     clone_fields = (
     clone_fields = (
         'site', 'location', 'tenant', 'status', 'role', 'type', 'width', 'u_height', 'desc_units', 'outer_width',
         'site', 'location', 'tenant', 'status', 'role', 'type', 'width', 'u_height', 'desc_units', 'outer_width',

+ 3 - 8
netbox/dcim/models/sites.py

@@ -8,6 +8,7 @@ from timezone_field import TimeZoneField
 from dcim.choices import *
 from dcim.choices import *
 from dcim.constants import *
 from dcim.constants import *
 from netbox.models import NestedGroupModel, PrimaryModel
 from netbox.models import NestedGroupModel, PrimaryModel
+from netbox.models.features import ImageAttachmentsMixin
 from utilities.fields import NaturalOrderingField
 from utilities.fields import NaturalOrderingField
 
 
 __all__ = (
 __all__ = (
@@ -136,7 +137,7 @@ class SiteGroup(NestedGroupModel):
 # Sites
 # Sites
 #
 #
 
 
-class Site(PrimaryModel):
+class Site(ImageAttachmentsMixin, PrimaryModel):
     """
     """
     A Site represents a geographic location within a network; typically a building or campus. The optional facility
     A Site represents a geographic location within a network; typically a building or campus. The optional facility
     field can be used to include an external designation, such as a data center name (e.g. Equinix SV6).
     field can be used to include an external designation, such as a data center name (e.g. Equinix SV6).
@@ -237,9 +238,6 @@ class Site(PrimaryModel):
     contacts = GenericRelation(
     contacts = GenericRelation(
         to='tenancy.ContactAssignment'
         to='tenancy.ContactAssignment'
     )
     )
-    images = GenericRelation(
-        to='extras.ImageAttachment'
-    )
 
 
     clone_fields = (
     clone_fields = (
         'status', 'region', 'group', 'tenant', 'facility', 'time_zone', 'physical_address', 'shipping_address',
         'status', 'region', 'group', 'tenant', 'facility', 'time_zone', 'physical_address', 'shipping_address',
@@ -265,7 +263,7 @@ class Site(PrimaryModel):
 # Locations
 # Locations
 #
 #
 
 
-class Location(NestedGroupModel):
+class Location(ImageAttachmentsMixin, NestedGroupModel):
     """
     """
     A Location represents a subgroup of Racks and/or Devices within a Site. A Location may represent a building within a
     A Location represents a subgroup of Racks and/or Devices within a Site. A Location may represent a building within a
     site, or a room within a building, for example.
     site, or a room within a building, for example.
@@ -299,9 +297,6 @@ class Location(NestedGroupModel):
     contacts = GenericRelation(
     contacts = GenericRelation(
         to='tenancy.ContactAssignment'
         to='tenancy.ContactAssignment'
     )
     )
-    images = GenericRelation(
-        to='extras.ImageAttachment'
-    )
 
 
     clone_fields = ('site', 'parent', 'status', 'tenant', 'description')
     clone_fields = ('site', 'parent', 'status', 'tenant', 'description')
     prerequisite_models = (
     prerequisite_models = (

+ 13 - 0
netbox/netbox/models/features.py

@@ -29,6 +29,7 @@ __all__ = (
     'CustomLinksMixin',
     'CustomLinksMixin',
     'CustomValidationMixin',
     'CustomValidationMixin',
     'ExportTemplatesMixin',
     'ExportTemplatesMixin',
+    'ImageAttachmentsMixin',
     'JobsMixin',
     'JobsMixin',
     'JournalingMixin',
     'JournalingMixin',
     'SyncedDataMixin',
     'SyncedDataMixin',
@@ -307,6 +308,18 @@ class ExportTemplatesMixin(models.Model):
         abstract = True
         abstract = True
 
 
 
 
+class ImageAttachmentsMixin(models.Model):
+    """
+    Enables the assignments of ImageAttachments.
+    """
+    images = GenericRelation(
+        to='extras.ImageAttachment'
+    )
+
+    class Meta:
+        abstract = True
+
+
 class BookmarksMixin(models.Model):
 class BookmarksMixin(models.Model):
     """
     """
     Enables support for user bookmarks.
     Enables support for user bookmarks.