Ver Fonte

Update help_texts for models, import forms

Jeremy Stretch há 5 anos atrás
pai
commit
718ff4a743

+ 2 - 8
netbox/circuits/forms.py

@@ -55,12 +55,6 @@ class ProviderCSVForm(CustomFieldModelCSVForm):
     class Meta:
         model = Provider
         fields = Provider.csv_headers
-        help_texts = {
-            'name': 'Provider name',
-            'asn': '32-bit autonomous system number',
-            'portal_url': 'Portal URL',
-            'comments': 'Free-form comments',
-        }
 
 
 class ProviderBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditForm):
@@ -195,7 +189,7 @@ class CircuitCSVForm(CustomFieldModelCSVForm):
     provider = forms.ModelChoiceField(
         queryset=Provider.objects.all(),
         to_field_name='name',
-        help_text='Name of parent provider',
+        help_text='Assigned provider',
         error_messages={
             'invalid_choice': 'Provider not found.'
         }
@@ -217,7 +211,7 @@ class CircuitCSVForm(CustomFieldModelCSVForm):
         queryset=Tenant.objects.all(),
         required=False,
         to_field_name='name',
-        help_text='Name of assigned tenant',
+        help_text='Assigned tenant',
         error_messages={
             'invalid_choice': 'Tenant not found.'
         }

+ 3 - 2
netbox/circuits/models.py

@@ -38,7 +38,8 @@ class Provider(ChangeLoggedModel, CustomFieldModel):
     asn = ASNField(
         blank=True,
         null=True,
-        verbose_name='ASN'
+        verbose_name='ASN',
+        help_text='32-bit autonomous system number'
     )
     account = models.CharField(
         max_length=30,
@@ -47,7 +48,7 @@ class Provider(ChangeLoggedModel, CustomFieldModel):
     )
     portal_url = models.URLField(
         blank=True,
-        verbose_name='Portal'
+        verbose_name='Portal URL'
     )
     noc_contact = models.TextField(
         blank=True,

+ 51 - 75
netbox/dcim/forms.py

@@ -5,6 +5,7 @@ from django.contrib.auth.models import User
 from django.contrib.contenttypes.models import ContentType
 from django.contrib.postgres.forms.array import SimpleArrayField
 from django.core.exceptions import ObjectDoesNotExist
+from django.utils.safestring import mark_safe
 from mptt.forms import TreeNodeChoiceField
 from netaddr import EUI
 from netaddr.core import AddrFormatError
@@ -206,10 +207,6 @@ class RegionCSVForm(forms.ModelForm):
     class Meta:
         model = Region
         fields = Region.csv_headers
-        help_texts = {
-            'name': 'Region name',
-            'slug': 'URL-friendly slug',
-        }
 
 
 class RegionFilterForm(BootstrapMixin, forms.Form):
@@ -280,7 +277,7 @@ class SiteCSVForm(CustomFieldModelCSVForm):
         queryset=Region.objects.all(),
         required=False,
         to_field_name='name',
-        help_text='Name of assigned region',
+        help_text='Assigned region',
         error_messages={
             'invalid_choice': 'Region not found.',
         }
@@ -289,7 +286,7 @@ class SiteCSVForm(CustomFieldModelCSVForm):
         queryset=Tenant.objects.all(),
         required=False,
         to_field_name='name',
-        help_text='Name of assigned tenant',
+        help_text='Assigned tenant',
         error_messages={
             'invalid_choice': 'Tenant not found.',
         }
@@ -299,9 +296,9 @@ class SiteCSVForm(CustomFieldModelCSVForm):
         model = Site
         fields = Site.csv_headers
         help_texts = {
-            'name': 'Site name',
-            'slug': 'URL-friendly slug',
-            'asn': '32-bit autonomous system number',
+            'time_zone': mark_safe(
+                'Time zone (<a href="https://en.wikipedia.org/wiki/List_of_tz_database_time_zones">available options</a>)'
+            )
         }
 
 
@@ -395,7 +392,7 @@ class RackGroupCSVForm(forms.ModelForm):
     site = forms.ModelChoiceField(
         queryset=Site.objects.all(),
         to_field_name='name',
-        help_text='Name of parent site',
+        help_text='Assigned site',
         error_messages={
             'invalid_choice': 'Site not found.',
         }
@@ -404,7 +401,7 @@ class RackGroupCSVForm(forms.ModelForm):
         queryset=RackGroup.objects.all(),
         required=False,
         to_field_name='name',
-        help_text='Name of parent rack group',
+        help_text='Parent rack group',
         error_messages={
             'invalid_choice': 'Rack group not found.',
         }
@@ -413,10 +410,6 @@ class RackGroupCSVForm(forms.ModelForm):
     class Meta:
         model = RackGroup
         fields = RackGroup.csv_headers
-        help_texts = {
-            'name': 'Name of rack group',
-            'slug': 'URL-friendly slug',
-        }
 
 
 class RackGroupFilterForm(BootstrapMixin, forms.Form):
@@ -475,8 +468,7 @@ class RackRoleCSVForm(forms.ModelForm):
         model = RackRole
         fields = RackRole.csv_headers
         help_texts = {
-            'name': 'Name of rack role',
-            'color': 'RGB color in hexadecimal (e.g. 00ff00)'
+            'color': mark_safe('RGB color in hexadecimal (e.g. <code>00ff00</code>)'),
         }
 
 
@@ -530,13 +522,11 @@ class RackCSVForm(CustomFieldModelCSVForm):
     site = forms.ModelChoiceField(
         queryset=Site.objects.all(),
         to_field_name='name',
-        help_text='Name of parent site',
         error_messages={
             'invalid_choice': 'Site not found.',
         }
     )
     group_name = forms.CharField(
-        help_text='Name of rack group',
         required=False
     )
     tenant = forms.ModelChoiceField(
@@ -580,10 +570,6 @@ class RackCSVForm(CustomFieldModelCSVForm):
     class Meta:
         model = Rack
         fields = Rack.csv_headers
-        help_texts = {
-            'name': 'Rack name',
-            'u_height': 'Height in rack units',
-        }
 
     def clean(self):
 
@@ -832,7 +818,7 @@ class RackReservationCSVForm(forms.ModelForm):
     site = forms.ModelChoiceField(
         queryset=Site.objects.all(),
         to_field_name='name',
-        help_text='Name of parent site',
+        help_text='Parent site',
         error_messages={
             'invalid_choice': 'Invalid site name.',
         }
@@ -853,7 +839,7 @@ class RackReservationCSVForm(forms.ModelForm):
         queryset=Tenant.objects.all(),
         required=False,
         to_field_name='name',
-        help_text='Name of assigned tenant',
+        help_text='Assigned tenant',
         error_messages={
             'invalid_choice': 'Tenant not found.',
         }
@@ -862,8 +848,6 @@ class RackReservationCSVForm(forms.ModelForm):
     class Meta:
         model = RackReservation
         fields = ('site', 'rack_group', 'rack_name', 'units', 'tenant', 'description')
-        help_texts = {
-        }
 
     def clean(self):
 
@@ -954,10 +938,6 @@ class ManufacturerCSVForm(forms.ModelForm):
     class Meta:
         model = Manufacturer
         fields = Manufacturer.csv_headers
-        help_texts = {
-            'name': 'Manufacturer name',
-            'slug': 'URL-friendly slug',
-        }
 
 
 #
@@ -1675,8 +1655,7 @@ class DeviceRoleCSVForm(forms.ModelForm):
         model = DeviceRole
         fields = DeviceRole.csv_headers
         help_texts = {
-            'name': 'Name of device role',
-            'color': 'RGB color in hexadecimal (e.g. 00ff00)'
+            'color': mark_safe('RGB color in hexadecimal (e.g. <code>00ff00</code>)'),
         }
 
 
@@ -1709,7 +1688,7 @@ class PlatformCSVForm(forms.ModelForm):
         queryset=Manufacturer.objects.all(),
         required=False,
         to_field_name='name',
-        help_text='Manufacturer name',
+        help_text='Limit platform assignments to this manufacturer',
         error_messages={
             'invalid_choice': 'Manufacturer not found.',
         }
@@ -1718,9 +1697,6 @@ class PlatformCSVForm(forms.ModelForm):
     class Meta:
         model = Platform
         fields = Platform.csv_headers
-        help_texts = {
-            'name': 'Platform name',
-        }
 
 
 #
@@ -1925,7 +1901,7 @@ class BaseDeviceCSVForm(CustomFieldModelCSVForm):
     device_role = forms.ModelChoiceField(
         queryset=DeviceRole.objects.all(),
         to_field_name='name',
-        help_text='Name of assigned role',
+        help_text='Assigned role',
         error_messages={
             'invalid_choice': 'Invalid device role.',
         }
@@ -1934,7 +1910,7 @@ class BaseDeviceCSVForm(CustomFieldModelCSVForm):
         queryset=Tenant.objects.all(),
         required=False,
         to_field_name='name',
-        help_text='Name of assigned tenant',
+        help_text='Assigned tenant',
         error_messages={
             'invalid_choice': 'Tenant not found.',
         }
@@ -1954,7 +1930,7 @@ class BaseDeviceCSVForm(CustomFieldModelCSVForm):
         queryset=Platform.objects.all(),
         required=False,
         to_field_name='name',
-        help_text='Name of assigned platform',
+        help_text='Assigned platform',
         error_messages={
             'invalid_choice': 'Invalid platform.',
         }
@@ -1963,13 +1939,19 @@ class BaseDeviceCSVForm(CustomFieldModelCSVForm):
         choices=DeviceStatusChoices,
         help_text='Operational status'
     )
+    cluster = forms.ModelChoiceField(
+        queryset=Cluster.objects.all(),
+        to_field_name='name',
+        required=False,
+        help_text='Virtualization cluster',
+        error_messages={
+            'invalid_choice': 'Invalid cluster name.',
+        }
+    )
 
     class Meta:
         fields = []
         model = Device
-        help_texts = {
-            'name': 'Device name',
-        }
 
     def clean(self):
 
@@ -1990,14 +1972,14 @@ class DeviceCSVForm(BaseDeviceCSVForm):
     site = forms.ModelChoiceField(
         queryset=Site.objects.all(),
         to_field_name='name',
-        help_text='Name of parent site',
+        help_text='Assigned site',
         error_messages={
             'invalid_choice': 'Invalid site name.',
         }
     )
     rack_group = forms.CharField(
         required=False,
-        help_text='Parent rack\'s group (if any)'
+        help_text='Assigned rack\'s group (if any)'
     )
     rack_name = forms.CharField(
         required=False,
@@ -2008,15 +1990,6 @@ class DeviceCSVForm(BaseDeviceCSVForm):
         required=False,
         help_text='Mounted rack face'
     )
-    cluster = forms.ModelChoiceField(
-        queryset=Cluster.objects.all(),
-        to_field_name='name',
-        required=False,
-        help_text='Virtualization cluster',
-        error_messages={
-            'invalid_choice': 'Invalid cluster name.',
-        }
-    )
 
     class Meta(BaseDeviceCSVForm.Meta):
         fields = [
@@ -2057,15 +2030,6 @@ class ChildDeviceCSVForm(BaseDeviceCSVForm):
     device_bay_name = forms.CharField(
         help_text='Name of device bay',
     )
-    cluster = forms.ModelChoiceField(
-        queryset=Cluster.objects.all(),
-        to_field_name='name',
-        required=False,
-        help_text='Virtualization cluster',
-        error_messages={
-            'invalid_choice': 'Invalid cluster name.',
-        }
-    )
 
     class Meta(BaseDeviceCSVForm.Meta):
         fields = [
@@ -2744,6 +2708,7 @@ class PowerOutletCSVForm(forms.ModelForm):
         queryset=PowerPort.objects.all(),
         required=False,
         to_field_name='name',
+        help_text='Local power port which feeds this outlet',
         error_messages={
             'invalid_choice': 'Power port not found.',
         }
@@ -2751,6 +2716,7 @@ class PowerOutletCSVForm(forms.ModelForm):
     feed_leg = CSVChoiceField(
         choices=PowerOutletFeedLegChoices,
         required=False,
+        help_text='Electrical phase (for three-phase circuits)'
     )
 
     class Meta:
@@ -3073,17 +3039,19 @@ class InterfaceCSVForm(forms.ModelForm):
         queryset=Interface.objects.all(),
         required=False,
         to_field_name='name',
-        help_text='LAG interface',
+        help_text='Parent LAG interface',
         error_messages={
             'invalid_choice': 'LAG interface not found.',
         }
     )
     type = CSVChoiceField(
         choices=InterfaceTypeChoices,
+        help_text='Physical medium'
     )
     mode = CSVChoiceField(
         choices=InterfaceModeChoices,
         required=False,
+        help_text='IEEE 802.1Q operational mode (for L2 interfaces)'
     )
 
     class Meta:
@@ -3274,17 +3242,22 @@ class FrontPortCSVForm(forms.ModelForm):
     rear_port = forms.ModelChoiceField(
         queryset=RearPort.objects.all(),
         to_field_name='name',
+        help_text='Corresponding rear port',
         error_messages={
             'invalid_choice': 'Rear Port not found.',
         }
     )
     type = CSVChoiceField(
         choices=PortTypeChoices,
+        help_text='Physical medium classification'
     )
 
     class Meta:
         model = FrontPort
         fields = FrontPort.csv_headers
+        help_texts = {
+            'rear_port_position': 'Mapped position on corresponding rear port',
+        }
 
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
@@ -3408,12 +3381,16 @@ class RearPortCSVForm(forms.ModelForm):
         }
     )
     type = CSVChoiceField(
+        help_text='Physical medium classification',
         choices=PortTypeChoices,
     )
 
     class Meta:
         model = RearPort
         fields = RearPort.csv_headers
+        help_texts = {
+            'positions': 'Number of front ports which may be mapped'
+        }
 
 
 #
@@ -3518,6 +3495,7 @@ class DeviceBayCSVForm(forms.ModelForm):
         queryset=Device.objects.all(),
         required=False,
         to_field_name='name',
+        help_text='Child device installed within this bay',
         error_messages={
             'invalid_choice': 'Child device not found.',
         }
@@ -3797,7 +3775,6 @@ class CableForm(BootstrapMixin, forms.ModelForm):
 
 
 class CableCSVForm(forms.ModelForm):
-
     # Termination A
     side_a_device = forms.ModelChoiceField(
         queryset=Device.objects.all(),
@@ -3814,7 +3791,7 @@ class CableCSVForm(forms.ModelForm):
         help_text='Side A type'
     )
     side_a_name = forms.CharField(
-        help_text='Side A component'
+        help_text='Side A component name'
     )
 
     # Termination B
@@ -3833,7 +3810,7 @@ class CableCSVForm(forms.ModelForm):
         help_text='Side B type'
     )
     side_b_name = forms.CharField(
-        help_text='Side B component'
+        help_text='Side B component name'
     )
 
     # Cable attributes
@@ -3845,7 +3822,7 @@ class CableCSVForm(forms.ModelForm):
     type = CSVChoiceField(
         choices=CableTypeChoices,
         required=False,
-        help_text='Cable type'
+        help_text='Physical medium classification'
     )
     length_unit = CSVChoiceField(
         choices=CableLengthUnitChoices,
@@ -3860,7 +3837,7 @@ class CableCSVForm(forms.ModelForm):
             'status', 'label', 'color', 'length', 'length_unit',
         ]
         help_texts = {
-            'color': 'RGB color in hexadecimal (e.g. 00ff00)'
+            'color': mark_safe('RGB color in hexadecimal (e.g. <code>00ff00</code>)'),
         }
 
     # TODO: Merge the clean() methods for either end
@@ -4163,7 +4140,6 @@ class InventoryItemCSVForm(forms.ModelForm):
         queryset=Manufacturer.objects.all(),
         to_field_name='name',
         required=False,
-        help_text='Manufacturer name',
         error_messages={
             'invalid_choice': 'Invalid manufacturer.',
         }
@@ -4614,7 +4590,7 @@ class PowerFeedCSVForm(CustomFieldModelCSVForm):
     site = forms.ModelChoiceField(
         queryset=Site.objects.all(),
         to_field_name='name',
-        help_text='Name of parent site',
+        help_text='Assigned site',
         error_messages={
             'invalid_choice': 'Site not found.',
         }
@@ -4622,18 +4598,18 @@ class PowerFeedCSVForm(CustomFieldModelCSVForm):
     panel_name = forms.ModelChoiceField(
         queryset=PowerPanel.objects.all(),
         to_field_name='name',
-        help_text='Name of upstream power panel',
+        help_text='Upstream power panel',
         error_messages={
             'invalid_choice': 'Power panel not found.',
         }
     )
     rack_group = forms.CharField(
         required=False,
-        help_text="Rack group name (optional)"
+        help_text="Assigned rack's group name"
     )
     rack_name = forms.CharField(
         required=False,
-        help_text="Rack name (optional)"
+        help_text="Assigned rack name"
     )
     status = CSVChoiceField(
         choices=PowerFeedStatusChoices,
@@ -4648,7 +4624,7 @@ class PowerFeedCSVForm(CustomFieldModelCSVForm):
     supply = CSVChoiceField(
         choices=PowerFeedSupplyChoices,
         required=False,
-        help_text='AC/DC'
+        help_text='Supply type (AC/DC)'
     )
     phase = CSVChoiceField(
         choices=PowerFeedPhaseChoices,

+ 20 - 10
netbox/dcim/models/__init__.py

@@ -179,12 +179,14 @@ class Site(ChangeLoggedModel, CustomFieldModel):
     )
     facility = models.CharField(
         max_length=50,
-        blank=True
+        blank=True,
+        help_text='Local facility ID or description'
     )
     asn = ASNField(
         blank=True,
         null=True,
-        verbose_name='ASN'
+        verbose_name='ASN',
+        help_text='32-bit autonomous system number'
     )
     time_zone = TimeZoneField(
         blank=True
@@ -205,13 +207,15 @@ class Site(ChangeLoggedModel, CustomFieldModel):
         max_digits=8,
         decimal_places=6,
         blank=True,
-        null=True
+        null=True,
+        help_text='GPS coordinate (latitude)'
     )
     longitude = models.DecimalField(
         max_digits=9,
         decimal_places=6,
         blank=True,
-        null=True
+        null=True,
+        help_text='GPS coordinate (longitude)'
     )
     contact_name = models.CharField(
         max_length=50,
@@ -418,7 +422,8 @@ class Rack(ChangeLoggedModel, CustomFieldModel):
         max_length=50,
         blank=True,
         null=True,
-        verbose_name='Facility ID'
+        verbose_name='Facility ID',
+        help_text='Locally-assigned identifier'
     )
     site = models.ForeignKey(
         to='dcim.Site',
@@ -430,7 +435,8 @@ class Rack(ChangeLoggedModel, CustomFieldModel):
         on_delete=models.SET_NULL,
         related_name='racks',
         blank=True,
-        null=True
+        null=True,
+        help_text='Assigned group'
     )
     tenant = models.ForeignKey(
         to='tenancy.Tenant',
@@ -449,7 +455,8 @@ class Rack(ChangeLoggedModel, CustomFieldModel):
         on_delete=models.PROTECT,
         related_name='racks',
         blank=True,
-        null=True
+        null=True,
+        help_text='Functional role'
     )
     serial = models.CharField(
         max_length=50,
@@ -479,7 +486,8 @@ class Rack(ChangeLoggedModel, CustomFieldModel):
     u_height = models.PositiveSmallIntegerField(
         default=RACK_U_HEIGHT_DEFAULT,
         verbose_name='Height (U)',
-        validators=[MinValueValidator(1), MaxValueValidator(100)]
+        validators=[MinValueValidator(1), MaxValueValidator(100)],
+        help_text='Height in rack units'
     )
     desc_units = models.BooleanField(
         default=False,
@@ -488,11 +496,13 @@ class Rack(ChangeLoggedModel, CustomFieldModel):
     )
     outer_width = models.PositiveSmallIntegerField(
         blank=True,
-        null=True
+        null=True,
+        help_text='Outer dimension of rack (width)'
     )
     outer_depth = models.PositiveSmallIntegerField(
         blank=True,
-        null=True
+        null=True,
+        help_text='Outer dimension of rack (depth)'
     )
     outer_unit = models.CharField(
         max_length=50,

+ 12 - 7
netbox/dcim/models/device_components.py

@@ -239,7 +239,8 @@ class ConsolePort(CableTermination, ComponentModel):
     type = models.CharField(
         max_length=50,
         choices=ConsolePortTypeChoices,
-        blank=True
+        blank=True,
+        help_text='Physical port type'
     )
     connected_endpoint = models.OneToOneField(
         to='dcim.ConsoleServerPort',
@@ -300,7 +301,8 @@ class ConsoleServerPort(CableTermination, ComponentModel):
     type = models.CharField(
         max_length=50,
         choices=ConsolePortTypeChoices,
-        blank=True
+        blank=True,
+        help_text='Physical port type'
     )
     connection_status = models.NullBooleanField(
         choices=CONNECTION_STATUS_CHOICES,
@@ -354,7 +356,8 @@ class PowerPort(CableTermination, ComponentModel):
     type = models.CharField(
         max_length=50,
         choices=PowerPortTypeChoices,
-        blank=True
+        blank=True,
+        help_text='Physical port type'
     )
     maximum_draw = models.PositiveSmallIntegerField(
         blank=True,
@@ -516,7 +519,8 @@ class PowerOutlet(CableTermination, ComponentModel):
     type = models.CharField(
         max_length=50,
         choices=PowerOutletTypeChoices,
-        blank=True
+        blank=True,
+        help_text='Physical port type'
     )
     power_port = models.ForeignKey(
         to='dcim.PowerPort',
@@ -653,7 +657,7 @@ class Interface(CableTermination, ComponentModel):
     mode = models.CharField(
         max_length=50,
         choices=InterfaceModeChoices,
-        blank=True,
+        blank=True
     )
     untagged_vlan = models.ForeignKey(
         to='ipam.VLAN',
@@ -1083,7 +1087,8 @@ class InventoryItem(ComponentModel):
     part_id = models.CharField(
         max_length=50,
         verbose_name='Part ID',
-        blank=True
+        blank=True,
+        help_text='Manufacturer-assigned part identifier'
     )
     serial = models.CharField(
         max_length=50,
@@ -1100,7 +1105,7 @@ class InventoryItem(ComponentModel):
     )
     discovered = models.BooleanField(
         default=False,
-        verbose_name='Discovered'
+        help_text='This item was automatically discovered'
     )
 
     tags = TaggableManager(through=TaggedItem)

+ 12 - 19
netbox/ipam/forms.py

@@ -55,7 +55,7 @@ class VRFCSVForm(CustomFieldModelCSVForm):
         queryset=Tenant.objects.all(),
         required=False,
         to_field_name='name',
-        help_text='Name of assigned tenant',
+        help_text='Assigned tenant',
         error_messages={
             'invalid_choice': 'Tenant not found.',
         }
@@ -64,9 +64,6 @@ class VRFCSVForm(CustomFieldModelCSVForm):
     class Meta:
         model = VRF
         fields = VRF.csv_headers
-        help_texts = {
-            'name': 'VRF name',
-        }
 
 
 class VRFBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditForm):
@@ -169,7 +166,7 @@ class AggregateCSVForm(CustomFieldModelCSVForm):
     rir = forms.ModelChoiceField(
         queryset=RIR.objects.all(),
         to_field_name='name',
-        help_text='Name of parent RIR',
+        help_text='Assigned RIR',
         error_messages={
             'invalid_choice': 'RIR not found.',
         }
@@ -251,9 +248,6 @@ class RoleCSVForm(forms.ModelForm):
     class Meta:
         model = Role
         fields = Role.csv_headers
-        help_texts = {
-            'name': 'Role name',
-        }
 
 
 #
@@ -335,6 +329,7 @@ class PrefixCSVForm(CustomFieldModelCSVForm):
         queryset=VRF.objects.all(),
         to_field_name='name',
         required=False,
+        help_text='Assigned VRF',
         error_messages={
             'invalid_choice': 'VRF not found.',
         }
@@ -343,7 +338,7 @@ class PrefixCSVForm(CustomFieldModelCSVForm):
         queryset=Tenant.objects.all(),
         required=False,
         to_field_name='name',
-        help_text='Name of assigned tenant',
+        help_text='Assigned tenant',
         error_messages={
             'invalid_choice': 'Tenant not found.',
         }
@@ -352,7 +347,7 @@ class PrefixCSVForm(CustomFieldModelCSVForm):
         queryset=Site.objects.all(),
         required=False,
         to_field_name='name',
-        help_text='Name of parent site',
+        help_text='Assigned site',
         error_messages={
             'invalid_choice': 'Site not found.',
         }
@@ -738,6 +733,7 @@ class IPAddressCSVForm(CustomFieldModelCSVForm):
         queryset=VRF.objects.all(),
         to_field_name='name',
         required=False,
+        help_text='Assigned VRF',
         error_messages={
             'invalid_choice': 'VRF not found.',
         }
@@ -746,7 +742,7 @@ class IPAddressCSVForm(CustomFieldModelCSVForm):
         queryset=Tenant.objects.all(),
         to_field_name='name',
         required=False,
-        help_text='Name of the assigned tenant',
+        help_text='Assigned tenant',
         error_messages={
             'invalid_choice': 'Tenant not found.',
         }
@@ -994,7 +990,7 @@ class VLANGroupCSVForm(forms.ModelForm):
         queryset=Site.objects.all(),
         required=False,
         to_field_name='name',
-        help_text='Name of parent site',
+        help_text='Assigned site',
         error_messages={
             'invalid_choice': 'Site not found.',
         }
@@ -1004,9 +1000,6 @@ class VLANGroupCSVForm(forms.ModelForm):
     class Meta:
         model = VLANGroup
         fields = VLANGroup.csv_headers
-        help_texts = {
-            'name': 'Name of VLAN group',
-        }
 
 
 class VLANGroupFilterForm(BootstrapMixin, forms.Form):
@@ -1082,7 +1075,7 @@ class VLANCSVForm(CustomFieldModelCSVForm):
         queryset=Site.objects.all(),
         required=False,
         to_field_name='name',
-        help_text='Name of parent site',
+        help_text='Assigned site',
         error_messages={
             'invalid_choice': 'Site not found.',
         }
@@ -1095,7 +1088,7 @@ class VLANCSVForm(CustomFieldModelCSVForm):
         queryset=Tenant.objects.all(),
         to_field_name='name',
         required=False,
-        help_text='Name of assigned tenant',
+        help_text='Assigned tenant',
         error_messages={
             'invalid_choice': 'Tenant not found.',
         }
@@ -1299,6 +1292,7 @@ class ServiceCSVForm(CustomFieldModelCSVForm):
         queryset=Device.objects.all(),
         required=False,
         to_field_name='name',
+        help_text='Required if not assigned to a VM',
         error_messages={
             'invalid_choice': 'Device not found.',
         }
@@ -1307,6 +1301,7 @@ class ServiceCSVForm(CustomFieldModelCSVForm):
         queryset=VirtualMachine.objects.all(),
         required=False,
         to_field_name='name',
+        help_text='Required if not assigned to a device',
         error_messages={
             'invalid_choice': 'Virtual machine not found.',
         }
@@ -1319,8 +1314,6 @@ class ServiceCSVForm(CustomFieldModelCSVForm):
     class Meta:
         model = Service
         fields = Service.csv_headers
-        help_texts = {
-        }
 
 
 class ServiceBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):

+ 6 - 2
netbox/ipam/models.py

@@ -50,7 +50,8 @@ class VRF(ChangeLoggedModel, CustomFieldModel):
         unique=True,
         blank=True,
         null=True,
-        verbose_name='Route distinguisher'
+        verbose_name='Route distinguisher',
+        help_text='Unique route distinguisher (as defined in RFC 4364)'
     )
     tenant = models.ForeignKey(
         to='tenancy.Tenant',
@@ -1017,7 +1018,10 @@ class Service(ChangeLoggedModel, CustomFieldModel):
         choices=ServiceProtocolChoices
     )
     port = models.PositiveIntegerField(
-        validators=[MinValueValidator(SERVICE_PORT_MIN), MaxValueValidator(SERVICE_PORT_MAX)],
+        validators=[
+            MinValueValidator(SERVICE_PORT_MIN),
+            MaxValueValidator(SERVICE_PORT_MAX)
+        ],
         verbose_name='Port number'
     )
     ipaddresses = models.ManyToManyField(

+ 2 - 4
netbox/secrets/forms.py

@@ -61,9 +61,6 @@ class SecretRoleCSVForm(forms.ModelForm):
     class Meta:
         model = SecretRole
         fields = SecretRole.csv_headers
-        help_texts = {
-            'name': 'Name of secret role',
-        }
 
 
 #
@@ -123,6 +120,7 @@ class SecretCSVForm(CustomFieldModelCSVForm):
     device = forms.ModelChoiceField(
         queryset=Device.objects.all(),
         to_field_name='name',
+        help_text='Assigned device',
         error_messages={
             'invalid_choice': 'Device not found.',
         }
@@ -130,7 +128,7 @@ class SecretCSVForm(CustomFieldModelCSVForm):
     role = forms.ModelChoiceField(
         queryset=SecretRole.objects.all(),
         to_field_name='name',
-        help_text='Name of assigned role',
+        help_text='Assigned role',
         error_messages={
             'invalid_choice': 'Invalid secret role.',
         }

+ 2 - 9
netbox/tenancy/forms.py

@@ -37,7 +37,7 @@ class TenantGroupCSVForm(forms.ModelForm):
         queryset=TenantGroup.objects.all(),
         required=False,
         to_field_name='name',
-        help_text='Name of parent tenant group',
+        help_text='Parent group',
         error_messages={
             'invalid_choice': 'Tenant group not found.',
         }
@@ -47,9 +47,6 @@ class TenantGroupCSVForm(forms.ModelForm):
     class Meta:
         model = TenantGroup
         fields = TenantGroup.csv_headers
-        help_texts = {
-            'name': 'Group name',
-        }
 
 
 #
@@ -80,7 +77,7 @@ class TenantCSVForm(CustomFieldModelForm):
         queryset=TenantGroup.objects.all(),
         required=False,
         to_field_name='name',
-        help_text='Name of parent group',
+        help_text='Assigned group',
         error_messages={
             'invalid_choice': 'Group not found.'
         }
@@ -89,10 +86,6 @@ class TenantCSVForm(CustomFieldModelForm):
     class Meta:
         model = Tenant
         fields = Tenant.csv_headers
-        help_texts = {
-            'name': 'Tenant name',
-            'comments': 'Free-form comments'
-        }
 
 
 class TenantBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditForm):

+ 8 - 14
netbox/virtualization/forms.py

@@ -42,9 +42,6 @@ class ClusterTypeCSVForm(forms.ModelForm):
     class Meta:
         model = ClusterType
         fields = ClusterType.csv_headers
-        help_texts = {
-            'name': 'Name of cluster type',
-        }
 
 
 #
@@ -67,9 +64,6 @@ class ClusterGroupCSVForm(forms.ModelForm):
     class Meta:
         model = ClusterGroup
         fields = ClusterGroup.csv_headers
-        help_texts = {
-            'name': 'Name of cluster group',
-        }
 
 
 #
@@ -104,7 +98,7 @@ class ClusterCSVForm(CustomFieldModelCSVForm):
     type = forms.ModelChoiceField(
         queryset=ClusterType.objects.all(),
         to_field_name='name',
-        help_text='Name of cluster type',
+        help_text='Type of cluster',
         error_messages={
             'invalid_choice': 'Invalid cluster type name.',
         }
@@ -113,7 +107,7 @@ class ClusterCSVForm(CustomFieldModelCSVForm):
         queryset=ClusterGroup.objects.all(),
         to_field_name='name',
         required=False,
-        help_text='Name of cluster group',
+        help_text='Assigned cluster group',
         error_messages={
             'invalid_choice': 'Invalid cluster group name.',
         }
@@ -122,7 +116,7 @@ class ClusterCSVForm(CustomFieldModelCSVForm):
         queryset=Site.objects.all(),
         to_field_name='name',
         required=False,
-        help_text='Name of assigned site',
+        help_text='Assigned site',
         error_messages={
             'invalid_choice': 'Invalid site name.',
         }
@@ -131,7 +125,7 @@ class ClusterCSVForm(CustomFieldModelCSVForm):
         queryset=Tenant.objects.all(),
         to_field_name='name',
         required=False,
-        help_text='Name of assigned tenant',
+        help_text='Assigned tenant',
         error_messages={
             'invalid_choice': 'Invalid tenant name'
         }
@@ -410,7 +404,7 @@ class VirtualMachineCSVForm(CustomFieldModelCSVForm):
     cluster = forms.ModelChoiceField(
         queryset=Cluster.objects.all(),
         to_field_name='name',
-        help_text='Name of parent cluster',
+        help_text='Assigned cluster',
         error_messages={
             'invalid_choice': 'Invalid cluster name.',
         }
@@ -421,7 +415,7 @@ class VirtualMachineCSVForm(CustomFieldModelCSVForm):
         ),
         required=False,
         to_field_name='name',
-        help_text='Name of functional role',
+        help_text='Functional role',
         error_messages={
             'invalid_choice': 'Invalid role name.'
         }
@@ -430,7 +424,7 @@ class VirtualMachineCSVForm(CustomFieldModelCSVForm):
         queryset=Tenant.objects.all(),
         required=False,
         to_field_name='name',
-        help_text='Name of assigned tenant',
+        help_text='Assigned tenant',
         error_messages={
             'invalid_choice': 'Tenant not found.'
         }
@@ -439,7 +433,7 @@ class VirtualMachineCSVForm(CustomFieldModelCSVForm):
         queryset=Platform.objects.all(),
         required=False,
         to_field_name='name',
-        help_text='Name of assigned platform',
+        help_text='Assigned platform',
         error_messages={
             'invalid_choice': 'Invalid platform.',
         }