diff --git a/netbox/circuits/models/circuits.py b/netbox/circuits/models/circuits.py index af8b5f042..0643906af 100644 --- a/netbox/circuits/models/circuits.py +++ b/netbox/circuits/models/circuits.py @@ -25,6 +25,11 @@ class CircuitType(OrganizationalModel): def get_absolute_url(self): return reverse('circuits:circuittype', args=[self.pk]) + class Meta: + ordering = ('name',) + verbose_name = _('circuit type') + verbose_name_plural = _('circuit types') + class Circuit(PrimaryModel): """ @@ -131,6 +136,8 @@ class Circuit(PrimaryModel): name='%(app_label)s_%(class)s_unique_provideraccount_cid' ), ) + verbose_name = _('circuit') + verbose_name_plural = _('circuits') def __str__(self): return self.cid @@ -217,6 +224,8 @@ class CircuitTermination( name='%(app_label)s_%(class)s_unique_circuit_term_side' ), ) + verbose_name = _('circuit termination') + verbose_name_plural = _('circuit terminations') def __str__(self): return f'{self.circuit}: Termination {self.term_side}' diff --git a/netbox/circuits/models/providers.py b/netbox/circuits/models/providers.py index e28a82a79..5a4154709 100644 --- a/netbox/circuits/models/providers.py +++ b/netbox/circuits/models/providers.py @@ -44,6 +44,8 @@ class Provider(PrimaryModel): class Meta: ordering = ['name'] + verbose_name = _('provider') + verbose_name_plural = _('providers') def __str__(self): return self.name @@ -91,6 +93,8 @@ class ProviderAccount(PrimaryModel): condition=~Q(name="") ), ) + verbose_name = _('provider account') + verbose_name_plural = _('provider accounts') def __str__(self): if self.name: @@ -129,6 +133,8 @@ class ProviderNetwork(PrimaryModel): name='%(app_label)s_%(class)s_unique_provider_name' ), ) + verbose_name = _('provider network') + verbose_name_plural = _('provider networks') def __str__(self): return self.name diff --git a/netbox/core/management/commands/makemigrations.py b/netbox/core/management/commands/makemigrations.py index 089a7cd18..10874418a 100644 --- a/netbox/core/management/commands/makemigrations.py +++ b/netbox/core/management/commands/makemigrations.py @@ -3,9 +3,15 @@ from django.conf import settings from django.core.management.base import CommandError from django.core.management.commands.makemigrations import Command as _Command from django.db import models +from django.db.migrations.operations import AlterModelOptions from utilities.migration import custom_deconstruct +# Monkey patch AlterModelOptions to ignore verbose name attributes +AlterModelOptions.ALTER_OPTION_KEYS.remove('verbose_name') +AlterModelOptions.ALTER_OPTION_KEYS.remove('verbose_name_plural') + +# Set our custom deconstructor for fields models.Field.deconstruct = custom_deconstruct diff --git a/netbox/core/models/data.py b/netbox/core/models/data.py index 87ca909c2..8e372c2eb 100644 --- a/netbox/core/models/data.py +++ b/netbox/core/models/data.py @@ -83,6 +83,8 @@ class DataSource(JobsMixin, PrimaryModel): class Meta: ordering = ('name',) + verbose_name = _('data source') + verbose_name_plural = _('data sources') def __str__(self): return f'{self.name}' @@ -300,6 +302,8 @@ class DataFile(models.Model): indexes = [ models.Index(fields=('source', 'path'), name='core_datafile_source_path'), ] + verbose_name = _('data file') + verbose_name_plural = _('data files') def __str__(self): return self.path @@ -383,3 +387,5 @@ class AutoSyncRecord(models.Model): indexes = ( models.Index(fields=('object_type', 'object_id')), ) + verbose_name = _('auto sync record') + verbose_name_plural = _('auto sync records') diff --git a/netbox/core/models/files.py b/netbox/core/models/files.py index c70f4c4fa..38d82463e 100644 --- a/netbox/core/models/files.py +++ b/netbox/core/models/files.py @@ -56,6 +56,8 @@ class ManagedFile(SyncedDataMixin, models.Model): indexes = [ models.Index(fields=('file_root', 'file_path'), name='core_managedfile_root_path'), ] + verbose_name = _('managed file') + verbose_name_plural = _('managed files') def __str__(self): return self.name diff --git a/netbox/core/models/jobs.py b/netbox/core/models/jobs.py index 63a918eb5..61b0e64fa 100644 --- a/netbox/core/models/jobs.py +++ b/netbox/core/models/jobs.py @@ -101,6 +101,8 @@ class Job(models.Model): class Meta: ordering = ['-created'] + verbose_name = _('job') + verbose_name_plural = _('jobs') def __str__(self): return str(self.job_id) diff --git a/netbox/dcim/models/cables.py b/netbox/dcim/models/cables.py index 5212dbff3..de7ba0eb6 100644 --- a/netbox/dcim/models/cables.py +++ b/netbox/dcim/models/cables.py @@ -91,6 +91,8 @@ class Cable(PrimaryModel): class Meta: ordering = ('pk',) + verbose_name = _('cable') + verbose_name_plural = _('cables') def __init__(self, *args, a_terminations=None, b_terminations=None, **kwargs): super().__init__(*args, **kwargs) @@ -292,6 +294,8 @@ class CableTermination(ChangeLoggedModel): name='%(app_label)s_%(class)s_unique_termination' ), ) + verbose_name = _('cable termination') + verbose_name_plural = _('cable terminations') def __str__(self): return f'Cable {self.cable} to {self.termination}' @@ -427,6 +431,10 @@ class CablePath(models.Model): ) _nodes = PathField() + class Meta: + verbose_name = _('cable path') + verbose_name_plural = _('cable paths') + def __str__(self): return f"Path #{self.pk}: {len(self.path)} hops" diff --git a/netbox/dcim/models/device_component_templates.py b/netbox/dcim/models/device_component_templates.py index 94ff2a8ce..f58d2bbca 100644 --- a/netbox/dcim/models/device_component_templates.py +++ b/netbox/dcim/models/device_component_templates.py @@ -183,6 +183,10 @@ class ConsolePortTemplate(ModularComponentTemplateModel): component_model = ConsolePort + class Meta(ModularComponentTemplateModel.Meta): + verbose_name = _('console port template') + verbose_name_plural = _('console port templates') + def instantiate(self, **kwargs): return self.component_model( name=self.resolve_name(kwargs.get('module')), @@ -213,6 +217,10 @@ class ConsoleServerPortTemplate(ModularComponentTemplateModel): component_model = ConsoleServerPort + class Meta(ModularComponentTemplateModel.Meta): + verbose_name = _('console server port template') + verbose_name_plural = _('console server port templates') + def instantiate(self, **kwargs): return self.component_model( name=self.resolve_name(kwargs.get('module')), @@ -258,6 +266,10 @@ class PowerPortTemplate(ModularComponentTemplateModel): component_model = PowerPort + class Meta(ModularComponentTemplateModel.Meta): + verbose_name = _('power port template') + verbose_name_plural = _('power port templates') + def instantiate(self, **kwargs): return self.component_model( name=self.resolve_name(kwargs.get('module')), @@ -316,6 +328,10 @@ class PowerOutletTemplate(ModularComponentTemplateModel): component_model = PowerOutlet + class Meta(ModularComponentTemplateModel.Meta): + verbose_name = _('power outlet template') + verbose_name_plural = _('power outlet templates') + def clean(self): super().clean() @@ -410,6 +426,10 @@ class InterfaceTemplate(ModularComponentTemplateModel): component_model = Interface + class Meta(ModularComponentTemplateModel.Meta): + verbose_name = _('interface template') + verbose_name_plural = _('interface templates') + def clean(self): super().clean() @@ -503,6 +523,8 @@ class FrontPortTemplate(ModularComponentTemplateModel): name='%(app_label)s_%(class)s_unique_rear_port_position' ), ) + verbose_name = _('front port template') + verbose_name_plural = _('front port templates') def clean(self): super().clean() @@ -579,6 +601,10 @@ class RearPortTemplate(ModularComponentTemplateModel): component_model = RearPort + class Meta(ModularComponentTemplateModel.Meta): + verbose_name = _('rear port template') + verbose_name_plural = _('rear port templates') + def instantiate(self, **kwargs): return self.component_model( name=self.resolve_name(kwargs.get('module')), @@ -614,6 +640,10 @@ class ModuleBayTemplate(ComponentTemplateModel): component_model = ModuleBay + class Meta(ComponentTemplateModel.Meta): + verbose_name = _('module bay template') + verbose_name_plural = _('module bay templates') + def instantiate(self, device): return self.component_model( device=device, @@ -638,6 +668,10 @@ class DeviceBayTemplate(ComponentTemplateModel): """ component_model = DeviceBay + class Meta(ComponentTemplateModel.Meta): + verbose_name = _('device bay template') + verbose_name_plural = _('device bay templates') + def instantiate(self, device): return self.component_model( device=device, @@ -720,6 +754,8 @@ class InventoryItemTemplate(MPTTModel, ComponentTemplateModel): name='%(app_label)s_%(class)s_unique_device_type_parent_name' ), ) + verbose_name = _('inventory item template') + verbose_name_plural = _('inventory item templates') def instantiate(self, **kwargs): parent = InventoryItem.objects.get(name=self.parent.name, **kwargs) if self.parent else None diff --git a/netbox/dcim/models/device_components.py b/netbox/dcim/models/device_components.py index 03ee33a63..e18f25e4f 100644 --- a/netbox/dcim/models/device_components.py +++ b/netbox/dcim/models/device_components.py @@ -298,6 +298,10 @@ class ConsolePort(ModularComponentModel, CabledObjectModel, PathEndpoint, Tracki clone_fields = ('device', 'module', 'type', 'speed') + class Meta(ModularComponentModel.Meta): + verbose_name = _('console port') + verbose_name_plural = _('console ports') + def get_absolute_url(self): return reverse('dcim:consoleport', kwargs={'pk': self.pk}) @@ -323,6 +327,10 @@ class ConsoleServerPort(ModularComponentModel, CabledObjectModel, PathEndpoint, clone_fields = ('device', 'module', 'type', 'speed') + class Meta(ModularComponentModel.Meta): + verbose_name = _('console server port') + verbose_name_plural = _('console server ports') + def get_absolute_url(self): return reverse('dcim:consoleserverport', kwargs={'pk': self.pk}) @@ -359,6 +367,10 @@ class PowerPort(ModularComponentModel, CabledObjectModel, PathEndpoint, Tracking clone_fields = ('device', 'module', 'maximum_draw', 'allocated_draw') + class Meta(ModularComponentModel.Meta): + verbose_name = _('power port') + verbose_name_plural = _('power ports') + def get_absolute_url(self): return reverse('dcim:powerport', kwargs={'pk': self.pk}) @@ -473,6 +485,10 @@ class PowerOutlet(ModularComponentModel, CabledObjectModel, PathEndpoint, Tracki clone_fields = ('device', 'module', 'type', 'power_port', 'feed_leg') + class Meta(ModularComponentModel.Meta): + verbose_name = _('power outlet') + verbose_name_plural = _('power outlets') + def get_absolute_url(self): return reverse('dcim:poweroutlet', kwargs={'pk': self.pk}) @@ -718,6 +734,8 @@ class Interface(ModularComponentModel, BaseInterface, CabledObjectModel, PathEnd class Meta(ModularComponentModel.Meta): ordering = ('device', CollateAsChar('_name')) + verbose_name = _('interface') + verbose_name_plural = _('interfaces') def get_absolute_url(self): return reverse('dcim:interface', kwargs={'pk': self.pk}) @@ -977,6 +995,8 @@ class FrontPort(ModularComponentModel, CabledObjectModel, TrackingModelMixin): name='%(app_label)s_%(class)s_unique_rear_port_position' ), ) + verbose_name = _('front port') + verbose_name_plural = _('front ports') def get_absolute_url(self): return reverse('dcim:frontport', kwargs={'pk': self.pk}) @@ -1032,6 +1052,10 @@ class RearPort(ModularComponentModel, CabledObjectModel, TrackingModelMixin): ) clone_fields = ('device', 'type', 'color', 'positions') + class Meta(ModularComponentModel.Meta): + verbose_name = _('rear port') + verbose_name_plural = _('rear ports') + def get_absolute_url(self): return reverse('dcim:rearport', kwargs={'pk': self.pk}) @@ -1066,6 +1090,10 @@ class ModuleBay(ComponentModel, TrackingModelMixin): clone_fields = ('device',) + class Meta(ComponentModel.Meta): + verbose_name = _('module bay') + verbose_name_plural = _('module bays') + def get_absolute_url(self): return reverse('dcim:modulebay', kwargs={'pk': self.pk}) @@ -1084,6 +1112,10 @@ class DeviceBay(ComponentModel, TrackingModelMixin): clone_fields = ('device',) + class Meta(ComponentModel.Meta): + verbose_name = _('device bay') + verbose_name_plural = _('device bays') + def get_absolute_url(self): return reverse('dcim:devicebay', kwargs={'pk': self.pk}) @@ -1125,6 +1157,11 @@ class InventoryItemRole(OrganizationalModel): default=ColorChoices.COLOR_GREY ) + class Meta: + ordering = ('name',) + verbose_name = _('inventory item role') + verbose_name_plural = _('inventory item roles') + def get_absolute_url(self): return reverse('dcim:inventoryitemrole', args=[self.pk]) @@ -1209,6 +1246,8 @@ class InventoryItem(MPTTModel, ComponentModel, TrackingModelMixin): name='%(app_label)s_%(class)s_unique_device_parent_name' ), ) + verbose_name = _('inventory item') + verbose_name_plural = _('inventory items') def get_absolute_url(self): return reverse('dcim:inventoryitem', kwargs={'pk': self.pk}) diff --git a/netbox/dcim/models/devices.py b/netbox/dcim/models/devices.py index 2b598704a..98784ea38 100644 --- a/netbox/dcim/models/devices.py +++ b/netbox/dcim/models/devices.py @@ -53,6 +53,11 @@ class Manufacturer(OrganizationalModel): to='tenancy.ContactAssignment' ) + class Meta: + ordering = ('name',) + verbose_name = _('manufacturer') + verbose_name_plural = _('manufacturers') + def get_absolute_url(self): return reverse('dcim:manufacturer', args=[self.pk]) @@ -199,6 +204,8 @@ class DeviceType(PrimaryModel, WeightMixin): name='%(app_label)s_%(class)s_unique_manufacturer_slug' ), ) + verbose_name = _('device type') + verbose_name_plural = _('device types') def __str__(self): return self.model @@ -400,6 +407,8 @@ class ModuleType(PrimaryModel, WeightMixin): name='%(app_label)s_%(class)s_unique_manufacturer_model' ), ) + verbose_name = _('module type') + verbose_name_plural = _('module types') def __str__(self): return self.model @@ -477,6 +486,11 @@ class DeviceRole(OrganizationalModel): null=True ) + class Meta: + ordering = ('name',) + verbose_name = _('device role') + verbose_name_plural = _('device roles') + def get_absolute_url(self): return reverse('dcim:devicerole', args=[self.pk]) @@ -502,6 +516,11 @@ class Platform(OrganizationalModel): null=True ) + class Meta: + ordering = ('name',) + verbose_name = _('platform') + verbose_name_plural = _('platforms') + def get_absolute_url(self): return reverse('dcim:platform', args=[self.pk]) @@ -789,6 +808,8 @@ class Device(PrimaryModel, ConfigContextModel, TrackingModelMixin): name='%(app_label)s_%(class)s_unique_virtual_chassis_vc_position' ), ) + verbose_name = _('device') + verbose_name_plural = _('devices') def __str__(self): if self.name and self.asset_tag: @@ -1182,6 +1203,8 @@ class Module(PrimaryModel, ConfigContextModel): class Meta: ordering = ('module_bay',) + verbose_name = _('module') + verbose_name_plural = _('modules') def __str__(self): return f'{self.module_bay.name}: {self.module_type} ({self.pk})' @@ -1314,7 +1337,8 @@ class VirtualChassis(PrimaryModel): class Meta: ordering = ['name'] - verbose_name_plural = 'virtual chassis' + verbose_name = _('virtual chassis') + verbose_name_plural = _('virtual chassis') def __str__(self): return self.name @@ -1415,6 +1439,8 @@ class VirtualDeviceContext(PrimaryModel): name='%(app_label)s_%(class)s_device_name' ), ) + verbose_name = _('virtual device context') + verbose_name_plural = _('virtual device contexts') def __str__(self): return self.name diff --git a/netbox/dcim/models/power.py b/netbox/dcim/models/power.py index 2c07388d4..3241ef840 100644 --- a/netbox/dcim/models/power.py +++ b/netbox/dcim/models/power.py @@ -60,6 +60,8 @@ class PowerPanel(PrimaryModel): name='%(app_label)s_%(class)s_unique_site_name' ), ) + verbose_name = _('power panel') + verbose_name_plural = _('power panels') def __str__(self): return self.name @@ -166,6 +168,8 @@ class PowerFeed(PrimaryModel, PathEndpoint, CabledObjectModel): name='%(app_label)s_%(class)s_unique_power_panel_name' ), ) + verbose_name = _('power feed') + verbose_name_plural = _('power feeds') def __str__(self): return self.name diff --git a/netbox/dcim/models/racks.py b/netbox/dcim/models/racks.py index 5fc24e724..12f938201 100644 --- a/netbox/dcim/models/racks.py +++ b/netbox/dcim/models/racks.py @@ -43,6 +43,11 @@ class RackRole(OrganizationalModel): default=ColorChoices.COLOR_GREY ) + class Meta: + ordering = ('name',) + verbose_name = _('rack role') + verbose_name_plural = _('rack roles') + def get_absolute_url(self): return reverse('dcim:rackrole', args=[self.pk]) @@ -216,6 +221,8 @@ class Rack(PrimaryModel, WeightMixin): name='%(app_label)s_%(class)s_unique_location_facility_id' ), ) + verbose_name = _('rack') + verbose_name_plural = _('racks') def __str__(self): if self.facility_id: @@ -538,6 +545,8 @@ class RackReservation(PrimaryModel): class Meta: ordering = ['created', 'pk'] + verbose_name = _('rack reservation') + verbose_name_plural = _('rack reservations') def __str__(self): return "Reservation for rack {}".format(self.rack) diff --git a/netbox/dcim/models/sites.py b/netbox/dcim/models/sites.py index 30d96e67d..087b87401 100644 --- a/netbox/dcim/models/sites.py +++ b/netbox/dcim/models/sites.py @@ -62,6 +62,8 @@ class Region(NestedGroupModel): violation_error_message=_("A top-level region with this slug already exists.") ), ) + verbose_name = _('region') + verbose_name_plural = _('regions') def get_absolute_url(self): return reverse('dcim:region', args=[self.pk]) @@ -117,6 +119,8 @@ class SiteGroup(NestedGroupModel): violation_error_message=_("A top-level site group with this slug already exists.") ), ) + verbose_name = _('site group') + verbose_name_plural = _('site groups') def get_absolute_url(self): return reverse('dcim:sitegroup', args=[self.pk]) @@ -244,6 +248,8 @@ class Site(PrimaryModel): class Meta: ordering = ('_name',) + verbose_name = _('site') + verbose_name_plural = _('sites') def __str__(self): return self.name @@ -326,6 +332,8 @@ class Location(NestedGroupModel): violation_error_message=_("A location with this slug already exists within the specified site.") ), ) + verbose_name = _('location') + verbose_name_plural = _('locations') def get_absolute_url(self): return reverse('dcim:location', args=[self.pk]) diff --git a/netbox/extras/models/change_logging.py b/netbox/extras/models/change_logging.py index f38533f80..ac9c60998 100644 --- a/netbox/extras/models/change_logging.py +++ b/netbox/extras/models/change_logging.py @@ -93,6 +93,8 @@ class ObjectChange(models.Model): class Meta: ordering = ['-time'] + verbose_name = _('object change') + verbose_name_plural = _('object changes') def __str__(self): return '{} {} {} by {}'.format( diff --git a/netbox/extras/models/configs.py b/netbox/extras/models/configs.py index 3ff51f393..6bd6019b9 100644 --- a/netbox/extras/models/configs.py +++ b/netbox/extras/models/configs.py @@ -125,6 +125,8 @@ class ConfigContext(SyncedDataMixin, CloningMixin, ChangeLoggedModel): class Meta: ordering = ['weight', 'name'] + verbose_name = _('config context') + verbose_name_plural = _('config contexts') def __str__(self): return self.name @@ -233,6 +235,8 @@ class ConfigTemplate(SyncedDataMixin, ExportTemplatesMixin, TagsMixin, ChangeLog class Meta: ordering = ('name',) + verbose_name = _('config template') + verbose_name_plural = _('config templates') def __str__(self): return self.name diff --git a/netbox/extras/models/customfields.py b/netbox/extras/models/customfields.py index 25ce14ddf..515b96225 100644 --- a/netbox/extras/models/customfields.py +++ b/netbox/extras/models/customfields.py @@ -202,6 +202,8 @@ class CustomField(CloningMixin, ExportTemplatesMixin, ChangeLoggedModel): class Meta: ordering = ['group_name', 'weight', 'name'] + verbose_name = _('custom field') + verbose_name_plural = _('custom fields') def __str__(self): return self.label or self.name.replace('_', ' ').capitalize() @@ -710,6 +712,8 @@ class CustomFieldChoiceSet(CloningMixin, ExportTemplatesMixin, ChangeLoggedModel class Meta: ordering = ('name',) + verbose_name = _('custom field choice set') + verbose_name_plural = _('custom field choice sets') def __str__(self): return self.name diff --git a/netbox/extras/models/dashboard.py b/netbox/extras/models/dashboard.py index 33bb735c4..7b9293777 100644 --- a/netbox/extras/models/dashboard.py +++ b/netbox/extras/models/dashboard.py @@ -25,7 +25,8 @@ class Dashboard(models.Model): ) class Meta: - pass + verbose_name = _('dashboard') + verbose_name_plural = _('dashboards') def get_widget(self, id): """ diff --git a/netbox/extras/models/models.py b/netbox/extras/models/models.py index 47aa557db..082891392 100644 --- a/netbox/extras/models/models.py +++ b/netbox/extras/models/models.py @@ -165,6 +165,8 @@ class Webhook(CustomFieldsMixin, ExportTemplatesMixin, TagsMixin, ChangeLoggedMo name='%(app_label)s_%(class)s_unique_payload_url_types' ), ) + verbose_name = _('webhook') + verbose_name_plural = _('webhooks') def __str__(self): return self.name @@ -284,6 +286,8 @@ class CustomLink(CloningMixin, ExportTemplatesMixin, ChangeLoggedModel): class Meta: ordering = ['group_name', 'weight', 'name'] + verbose_name = _('custom link') + verbose_name_plural = _('custom links') def __str__(self): return self.name @@ -371,6 +375,8 @@ class ExportTemplate(SyncedDataMixin, CloningMixin, ExportTemplatesMixin, Change class Meta: ordering = ('name',) + verbose_name = _('export template') + verbose_name_plural = _('export templates') def __str__(self): return self.name @@ -482,6 +488,8 @@ class SavedFilter(CloningMixin, ExportTemplatesMixin, ChangeLoggedModel): class Meta: ordering = ('weight', 'name') + verbose_name = _('saved filter') + verbose_name_plural = _('saved filters') def __str__(self): return self.name @@ -544,6 +552,8 @@ class ImageAttachment(ChangeLoggedModel): class Meta: ordering = ('name', 'pk') # name may be non-unique + verbose_name = _('image attachment') + verbose_name_plural = _('image attachments') def __str__(self): if self.name: @@ -622,7 +632,8 @@ class JournalEntry(CustomFieldsMixin, CustomLinksMixin, TagsMixin, ExportTemplat class Meta: ordering = ('-created',) - verbose_name_plural = 'journal entries' + verbose_name = _('journal entry') + verbose_name_plural = _('journal entries') def __str__(self): created = timezone.localtime(self.created) @@ -677,6 +688,8 @@ class Bookmark(models.Model): name='%(app_label)s_%(class)s_unique_per_object_and_user' ), ) + verbose_name = _('bookmark') + verbose_name_plural = _('bookmarks') def __str__(self): if self.object: @@ -707,6 +720,8 @@ class ConfigRevision(models.Model): class Meta: ordering = ['-created'] + verbose_name = _('config revision') + verbose_name_plural = _('config revisions') def __str__(self): return f'Config revision #{self.pk} ({self.created})' diff --git a/netbox/extras/models/reports.py b/netbox/extras/models/reports.py index f1e336df5..223d679bd 100644 --- a/netbox/extras/models/reports.py +++ b/netbox/extras/models/reports.py @@ -4,6 +4,7 @@ from functools import cached_property from django.db import models from django.urls import reverse +from django.utils.translation import gettext_lazy as _ from core.choices import ManagedFileRootPathChoices from core.models import ManagedFile @@ -42,6 +43,8 @@ class ReportModule(PythonModuleMixin, JobsMixin, ManagedFile): class Meta: proxy = True + verbose_name = _('report module') + verbose_name_plural = _('report modules') def get_absolute_url(self): return reverse('extras:report_list') diff --git a/netbox/extras/models/scripts.py b/netbox/extras/models/scripts.py index de48aae8e..122f56f20 100644 --- a/netbox/extras/models/scripts.py +++ b/netbox/extras/models/scripts.py @@ -4,6 +4,7 @@ from functools import cached_property from django.db import models from django.urls import reverse +from django.utils.translation import gettext_lazy as _ from core.choices import ManagedFileRootPathChoices from core.models import ManagedFile @@ -42,6 +43,8 @@ class ScriptModule(PythonModuleMixin, JobsMixin, ManagedFile): class Meta: proxy = True + verbose_name = _('script module') + verbose_name_plural = _('script modules') def get_absolute_url(self): return reverse('extras:script_list') diff --git a/netbox/extras/models/search.py b/netbox/extras/models/search.py index 052b43f89..debe4c648 100644 --- a/netbox/extras/models/search.py +++ b/netbox/extras/models/search.py @@ -51,6 +51,8 @@ class CachedValue(models.Model): class Meta: ordering = ('weight', 'object_type', 'object_id') + verbose_name = _('cached value') + verbose_name_plural = _('cached values') def __str__(self): return f'{self.object_type} {self.object_id}: {self.field}={self.value}' diff --git a/netbox/extras/models/staging.py b/netbox/extras/models/staging.py index cb0c6e704..b0df9e26e 100644 --- a/netbox/extras/models/staging.py +++ b/netbox/extras/models/staging.py @@ -41,6 +41,8 @@ class Branch(ChangeLoggedModel): class Meta: ordering = ('name',) + verbose_name = _('branch') + verbose_name_plural = _('branches') def __str__(self): return f'{self.name} ({self.pk})' @@ -89,6 +91,8 @@ class StagedChange(ChangeLoggedModel): class Meta: ordering = ('pk',) + verbose_name = _('staged change') + verbose_name_plural = _('staged changes') def __str__(self): action = self.get_action_display() diff --git a/netbox/extras/models/tags.py b/netbox/extras/models/tags.py index 3b19f62d9..f4ba5ea64 100644 --- a/netbox/extras/models/tags.py +++ b/netbox/extras/models/tags.py @@ -50,6 +50,8 @@ class Tag(CloningMixin, ExportTemplatesMixin, ChangeLoggedModel, TagBase): class Meta: ordering = ['name'] + verbose_name = _('tag') + verbose_name_plural = _('tags') def get_absolute_url(self): return reverse('extras:tag', args=[self.pk]) @@ -75,3 +77,5 @@ class TaggedItem(GenericTaggedItemBase): class Meta: indexes = [models.Index(fields=["content_type", "object_id"])] + verbose_name = _('tagged item') + verbose_name_plural = _('tagged items') diff --git a/netbox/ipam/models/asns.py b/netbox/ipam/models/asns.py index 57499c676..ba483a745 100644 --- a/netbox/ipam/models/asns.py +++ b/netbox/ipam/models/asns.py @@ -48,8 +48,8 @@ class ASNRange(OrganizationalModel): class Meta: ordering = ('name',) - verbose_name = 'ASN range' - verbose_name_plural = 'ASN ranges' + verbose_name = _('ASN range') + verbose_name_plural = _('ASN ranges') def __str__(self): return f'{self.name} ({self.range_as_string()})' @@ -122,8 +122,8 @@ class ASN(PrimaryModel): class Meta: ordering = ['asn'] - verbose_name = 'ASN' - verbose_name_plural = 'ASNs' + verbose_name = _('ASN') + verbose_name_plural = _('ASNs') def __str__(self): return f'AS{self.asn_with_asdot}' diff --git a/netbox/ipam/models/fhrp.py b/netbox/ipam/models/fhrp.py index 78c34db6a..5d355102f 100644 --- a/netbox/ipam/models/fhrp.py +++ b/netbox/ipam/models/fhrp.py @@ -54,7 +54,8 @@ class FHRPGroup(PrimaryModel): class Meta: ordering = ['protocol', 'group_id', 'pk'] - verbose_name = 'FHRP group' + verbose_name = _('FHRP group') + verbose_name_plural = _('FHRP groups') def __str__(self): name = '' @@ -108,6 +109,7 @@ class FHRPGroupAssignment(ChangeLoggedModel): ), ) verbose_name = _('FHRP group assignment') + verbose_name_plural = _('FHRP group assignments') def __str__(self): return f'{self.interface}: {self.group} ({self.priority})' diff --git a/netbox/ipam/models/ip.py b/netbox/ipam/models/ip.py index 174bcd672..553f5eb92 100644 --- a/netbox/ipam/models/ip.py +++ b/netbox/ipam/models/ip.py @@ -111,6 +111,8 @@ class Aggregate(GetAvailablePrefixesMixin, PrimaryModel): class Meta: ordering = ('prefix', 'pk') # prefix may be non-unique + verbose_name = _('aggregate') + verbose_name_plural = _('aggregates') def __str__(self): return str(self.prefix) @@ -188,6 +190,8 @@ class Role(OrganizationalModel): class Meta: ordering = ('weight', 'name') + verbose_name = _('role') + verbose_name_plural = _('roles') def __str__(self): return self.name @@ -279,7 +283,8 @@ class Prefix(GetAvailablePrefixesMixin, PrimaryModel): class Meta: ordering = (F('vrf').asc(nulls_first=True), 'prefix', 'pk') # (vrf, prefix) may be non-unique - verbose_name_plural = 'prefixes' + verbose_name = _('prefix') + verbose_name_plural = _('prefixes') def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -532,8 +537,8 @@ class IPRange(PrimaryModel): class Meta: ordering = (F('vrf').asc(nulls_first=True), 'start_address', 'pk') # (vrf, start_address) may be non-unique - verbose_name = 'IP range' - verbose_name_plural = 'IP ranges' + verbose_name = _('IP range') + verbose_name_plural = _('IP ranges') def __str__(self): return self.name @@ -783,8 +788,8 @@ class IPAddress(PrimaryModel): indexes = [ models.Index(Cast(Host('address'), output_field=IPAddressField()), name='ipam_ipaddress_host'), ] - verbose_name = 'IP address' - verbose_name_plural = 'IP addresses' + verbose_name = _('IP address') + verbose_name_plural = _('IP addresses') def __str__(self): return str(self.address) diff --git a/netbox/ipam/models/l2vpn.py b/netbox/ipam/models/l2vpn.py index 6234f3eea..7b3463f42 100644 --- a/netbox/ipam/models/l2vpn.py +++ b/netbox/ipam/models/l2vpn.py @@ -62,7 +62,8 @@ class L2VPN(PrimaryModel): class Meta: ordering = ('name', 'identifier') - verbose_name = 'L2VPN' + verbose_name = _('L2VPN') + verbose_name_plural = _('L2VPNs') def __str__(self): if self.identifier: @@ -105,13 +106,14 @@ class L2VPNTermination(NetBoxModel): class Meta: ordering = ('l2vpn',) - verbose_name = 'L2VPN termination' constraints = ( models.UniqueConstraint( fields=('assigned_object_type', 'assigned_object_id'), name='ipam_l2vpntermination_assigned_object' ), ) + verbose_name = _('L2VPN termination') + verbose_name_plural = _('L2VPN terminations') def __str__(self): if self.pk is not None: diff --git a/netbox/ipam/models/services.py b/netbox/ipam/models/services.py index 277b383a5..3e3261ee9 100644 --- a/netbox/ipam/models/services.py +++ b/netbox/ipam/models/services.py @@ -56,6 +56,8 @@ class ServiceTemplate(ServiceBase, PrimaryModel): class Meta: ordering = ('name',) + verbose_name = _('service template') + verbose_name_plural = _('service templates') def get_absolute_url(self): return reverse('ipam:servicetemplate', args=[self.pk]) @@ -97,6 +99,8 @@ class Service(ServiceBase, PrimaryModel): class Meta: ordering = ('protocol', 'ports', 'pk') # (protocol, port) may be non-unique + verbose_name = _('service') + verbose_name_plural = _('services') def get_absolute_url(self): return reverse('ipam:service', args=[self.pk]) diff --git a/netbox/ipam/models/vlans.py b/netbox/ipam/models/vlans.py index 3b9bd0095..927d01fa5 100644 --- a/netbox/ipam/models/vlans.py +++ b/netbox/ipam/models/vlans.py @@ -79,8 +79,8 @@ class VLANGroup(OrganizationalModel): name='%(app_label)s_%(class)s_unique_scope_slug' ), ) - verbose_name = 'VLAN group' - verbose_name_plural = 'VLAN groups' + verbose_name = _('VLAN group') + verbose_name_plural = _('VLAN groups') def get_absolute_url(self): return reverse('ipam:vlangroup', args=[self.pk]) @@ -204,8 +204,8 @@ class VLAN(PrimaryModel): name='%(app_label)s_%(class)s_unique_group_name' ), ) - verbose_name = 'VLAN' - verbose_name_plural = 'VLANs' + verbose_name = _('VLAN') + verbose_name_plural = _('VLANs') def __str__(self): return f'{self.name} ({self.vid})' diff --git a/netbox/ipam/models/vrfs.py b/netbox/ipam/models/vrfs.py index d338e2dcd..1f9b928f5 100644 --- a/netbox/ipam/models/vrfs.py +++ b/netbox/ipam/models/vrfs.py @@ -59,8 +59,8 @@ class VRF(PrimaryModel): class Meta: ordering = ('name', 'rd', 'pk') # (name, rd) may be non-unique - verbose_name = 'VRF' - verbose_name_plural = 'VRFs' + verbose_name = _('VRF') + verbose_name_plural = _('VRFs') def __str__(self): if self.rd: @@ -91,6 +91,8 @@ class RouteTarget(PrimaryModel): class Meta: ordering = ['name'] + verbose_name = _('route target') + verbose_name_plural = _('route targets') def __str__(self): return self.name diff --git a/netbox/tenancy/models/contacts.py b/netbox/tenancy/models/contacts.py index 71c1903ac..e8327248d 100644 --- a/netbox/tenancy/models/contacts.py +++ b/netbox/tenancy/models/contacts.py @@ -28,6 +28,8 @@ class ContactGroup(NestedGroupModel): name='%(app_label)s_%(class)s_unique_parent_name' ), ) + verbose_name = _('contact group') + verbose_name_plural = _('contact groups') def get_absolute_url(self): return reverse('tenancy:contactgroup', args=[self.pk]) @@ -40,6 +42,11 @@ class ContactRole(OrganizationalModel): def get_absolute_url(self): return reverse('tenancy:contactrole', args=[self.pk]) + class Meta: + ordering = ('name',) + verbose_name = _('contact role') + verbose_name_plural = _('contact roles') + class Contact(PrimaryModel): """ @@ -92,6 +99,8 @@ class Contact(PrimaryModel): name='%(app_label)s_%(class)s_unique_group_name' ), ) + verbose_name = _('contact') + verbose_name_plural = _('contacts') def __str__(self): return self.name @@ -137,6 +146,8 @@ class ContactAssignment(ChangeLoggedModel, TagsMixin): name='%(app_label)s_%(class)s_unique_object_contact_role' ), ) + verbose_name = _('contact assignment') + verbose_name_plural = _('contact assignments') def __str__(self): if self.priority: diff --git a/netbox/tenancy/models/tenants.py b/netbox/tenancy/models/tenants.py index bcd0a4452..ab08bd812 100644 --- a/netbox/tenancy/models/tenants.py +++ b/netbox/tenancy/models/tenants.py @@ -29,6 +29,8 @@ class TenantGroup(NestedGroupModel): class Meta: ordering = ['name'] + verbose_name = _('tenant group') + verbose_name_plural = _('tenant groups') def get_absolute_url(self): return reverse('tenancy:tenantgroup', args=[self.pk]) @@ -88,6 +90,8 @@ class Tenant(PrimaryModel): condition=Q(group__isnull=True) ), ) + verbose_name = _('tenant') + verbose_name_plural = _('tenants') def __str__(self): return self.name diff --git a/netbox/users/models.py b/netbox/users/models.py index 9c4024f1c..80fd0dd09 100644 --- a/netbox/users/models.py +++ b/netbox/users/models.py @@ -49,9 +49,10 @@ class NetBoxUser(User): objects = NetBoxUserManager() class Meta: - verbose_name = 'User' proxy = True ordering = ('username',) + verbose_name = _('user') + verbose_name_plural = _('users') def get_absolute_url(self): return reverse('users:netboxuser', args=[self.pk]) @@ -72,9 +73,10 @@ class NetBoxGroup(Group): objects = NetBoxGroupManager() class Meta: - verbose_name = 'Group' proxy = True ordering = ('name',) + verbose_name = _('group') + verbose_name_plural = _('groups') def get_absolute_url(self): return reverse('users:netboxgroup', args=[self.pk]) @@ -99,7 +101,8 @@ class UserConfig(models.Model): class Meta: ordering = ['user'] - verbose_name = verbose_name_plural = _('User Preferences') + verbose_name = _('user preferences') + verbose_name_plural = _('user preferences') def get(self, path, default=None): """ @@ -281,6 +284,10 @@ class Token(models.Model): objects = RestrictedQuerySet.as_manager() + class Meta: + verbose_name = _('token') + verbose_name_plural = _('tokens') + def __str__(self): return self.key if settings.ALLOW_TOKEN_RETRIEVAL else self.partial @@ -373,7 +380,8 @@ class ObjectPermission(models.Model): class Meta: ordering = ['name'] - verbose_name = _("permission") + verbose_name = _('permission') + verbose_name_plural = _('permissions') def __str__(self): return self.name diff --git a/netbox/virtualization/models/clusters.py b/netbox/virtualization/models/clusters.py index 0f48c50f0..aed064406 100644 --- a/netbox/virtualization/models/clusters.py +++ b/netbox/virtualization/models/clusters.py @@ -19,6 +19,11 @@ class ClusterType(OrganizationalModel): """ A type of Cluster. """ + class Meta: + ordering = ('name',) + verbose_name = _('cluster type') + verbose_name_plural = _('cluster types') + def get_absolute_url(self): return reverse('virtualization:clustertype', args=[self.pk]) @@ -38,6 +43,11 @@ class ClusterGroup(OrganizationalModel): to='tenancy.ContactAssignment' ) + class Meta: + ordering = ('name',) + verbose_name = _('cluster group') + verbose_name_plural = _('cluster groups') + def get_absolute_url(self): return reverse('virtualization:clustergroup', args=[self.pk]) @@ -114,6 +124,8 @@ class Cluster(PrimaryModel): name='%(app_label)s_%(class)s_unique_site_name' ), ) + verbose_name = _('cluster') + verbose_name_plural = _('clusters') def __str__(self): return self.name diff --git a/netbox/virtualization/models/virtualmachines.py b/netbox/virtualization/models/virtualmachines.py index 5620e4564..fd2ea86eb 100644 --- a/netbox/virtualization/models/virtualmachines.py +++ b/netbox/virtualization/models/virtualmachines.py @@ -157,6 +157,8 @@ class VirtualMachine(PrimaryModel, ConfigContextModel): violation_error_message=_("Virtual machine name must be unique per cluster.") ), ) + verbose_name = _('virtual machine') + verbose_name_plural = _('virtual machines') def __str__(self): return self.name @@ -307,7 +309,8 @@ class VMInterface(NetBoxModel, BaseInterface, TrackingModelMixin): name='%(app_label)s_%(class)s_unique_virtual_machine_name' ), ) - verbose_name = 'interface' + verbose_name = _('interface') + verbose_name_plural = _('interfaces') def __str__(self): return self.name diff --git a/netbox/wireless/models.py b/netbox/wireless/models.py index e49c99386..046918535 100644 --- a/netbox/wireless/models.py +++ b/netbox/wireless/models.py @@ -66,7 +66,8 @@ class WirelessLANGroup(NestedGroupModel): name='%(app_label)s_%(class)s_unique_parent_name' ), ) - verbose_name = 'Wireless LAN Group' + verbose_name = _('wireless LAN group') + verbose_name_plural = _('wireless LAN groups') def get_absolute_url(self): return reverse('wireless:wirelesslangroup', args=[self.pk]) @@ -112,7 +113,8 @@ class WirelessLAN(WirelessAuthenticationBase, PrimaryModel): class Meta: ordering = ('ssid', 'pk') - verbose_name = 'Wireless LAN' + verbose_name = _('wireless LAN') + verbose_name_plural = _('wireless LANs') def __str__(self): return self.ssid @@ -194,6 +196,8 @@ class WirelessLink(WirelessAuthenticationBase, PrimaryModel): name='%(app_label)s_%(class)s_unique_interfaces' ), ) + verbose_name = _('wireless link') + verbose_name_plural = _('wireless links') def __str__(self): return self.ssid or f'#{self.pk}'