13132 add gettext_lazy to models

This commit is contained in:
Arthur 2023-07-11 19:17:14 +07:00 committed by Jeremy Stretch
parent 90c9e71682
commit d051494cef
7 changed files with 83 additions and 45 deletions

View File

@ -1,3 +1,4 @@
from django.utils.translation import gettext_lazy as _
import django_tables2 as tables
from circuits.models import *
@ -53,19 +54,19 @@ class CircuitTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
)
provider_account = tables.Column(
linkify=True,
verbose_name='Account'
verbose_name=_('Account')
)
status = columns.ChoiceFieldColumn()
termination_a = tables.TemplateColumn(
template_code=CIRCUITTERMINATION_LINK,
verbose_name='Side A'
verbose_name=_('Side A')
)
termination_z = tables.TemplateColumn(
template_code=CIRCUITTERMINATION_LINK,
verbose_name='Side Z'
verbose_name=_('Side Z')
)
commit_rate = CommitRateColumn(
verbose_name='Commit Rate'
verbose_name=_('Commit Rate')
)
comments = columns.MarkdownColumn()
tags = columns.TagColumn(

View File

@ -2,6 +2,7 @@ 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 _
from netbox.models import ChangeLoggedModel, NestedGroupModel, OrganizationalModel, PrimaryModel
from tenancy.choices import *
@ -51,24 +52,30 @@ class Contact(PrimaryModel):
null=True
)
name = models.CharField(
verbose_name=_('name'),
max_length=100
)
title = models.CharField(
verbose_name=_('title'),
max_length=100,
blank=True
)
phone = models.CharField(
verbose_name=_('phone'),
max_length=50,
blank=True
)
email = models.EmailField(
verbose_name=_('email'),
blank=True
)
address = models.CharField(
verbose_name=_('address'),
max_length=200,
blank=True
)
link = models.URLField(
verbose_name=_('link'),
blank=True
)
@ -113,6 +120,7 @@ class ContactAssignment(ChangeLoggedModel):
related_name='assignments'
)
priority = models.CharField(
verbose_name=_('priority'),
max_length=50,
choices=ContactPriorityChoices,
blank=True

View File

@ -2,6 +2,7 @@ from django.contrib.contenttypes.fields import GenericRelation
from django.db import models
from django.db.models import Q
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from netbox.models import NestedGroupModel, PrimaryModel
@ -16,10 +17,12 @@ class TenantGroup(NestedGroupModel):
An arbitrary collection of Tenants.
"""
name = models.CharField(
verbose_name=_('name'),
max_length=100,
unique=True
)
slug = models.SlugField(
verbose_name=_('slug'),
max_length=100,
unique=True
)
@ -37,9 +40,11 @@ class Tenant(PrimaryModel):
department.
"""
name = models.CharField(
verbose_name=_('name'),
max_length=100
)
slug = models.SlugField(
verbose_name=_('slug'),
max_length=100
)
group = models.ForeignKey(
@ -65,7 +70,7 @@ class Tenant(PrimaryModel):
models.UniqueConstraint(
fields=('group', 'name'),
name='%(app_label)s_%(class)s_unique_group_name',
violation_error_message="Tenant name must be unique per group."
violation_error_message=_("Tenant name must be unique per group.")
),
models.UniqueConstraint(
fields=('name',),
@ -75,7 +80,7 @@ class Tenant(PrimaryModel):
models.UniqueConstraint(
fields=('group', 'slug'),
name='%(app_label)s_%(class)s_unique_group_slug',
violation_error_message="Tenant slug must be unique per group."
violation_error_message=_("Tenant slug must be unique per group.")
),
models.UniqueConstraint(
fields=('slug',),

View File

@ -11,7 +11,7 @@ from django.db.models.signals import post_save
from django.dispatch import receiver
from django.urls import reverse
from django.utils import timezone
from django.utils.translation import gettext as _
from django.utils.translation import gettext_lazy as _
from netaddr import IPNetwork
from ipam.fields import IPNetworkField
@ -40,7 +40,7 @@ class AdminGroup(Group):
Proxy contrib.auth.models.Group for the admin UI
"""
class Meta:
verbose_name = 'Group'
verbose_name = _('Group')
proxy = True
@ -49,7 +49,7 @@ class AdminUser(User):
Proxy contrib.auth.models.User for the admin UI
"""
class Meta:
verbose_name = 'User'
verbose_name = _('User')
proxy = True
@ -105,12 +105,13 @@ class UserConfig(models.Model):
related_name='config'
)
data = models.JSONField(
verbose_name=_('data'),
default=dict
)
class Meta:
ordering = ['user']
verbose_name = verbose_name_plural = 'User Preferences'
verbose_name = verbose_name_plural = _('User Preferences')
def get(self, path, default=None):
"""
@ -176,7 +177,7 @@ class UserConfig(models.Model):
d = d[key]
elif key in d:
err_path = '.'.join(path.split('.')[:i + 1])
raise TypeError(f"Key '{err_path}' is a leaf node; cannot assign new keys")
raise TypeError(_("Key '{err_path}' is a leaf node; cannot assign new keys").format(err_path=err_path))
else:
d = d.setdefault(key, {})
@ -186,7 +187,7 @@ class UserConfig(models.Model):
if type(value) is dict:
d[key].update(value)
else:
raise TypeError(f"Key '{path}' is a dictionary; cannot assign a non-dictionary value")
raise TypeError(_("Key '{path}' is a dictionary; cannot assign a non-dictionary value").format(path=path))
else:
d[key] = value
@ -246,26 +247,32 @@ class Token(models.Model):
related_name='tokens'
)
created = models.DateTimeField(
verbose_name=_('created'),
auto_now_add=True
)
expires = models.DateTimeField(
verbose_name=_('expires'),
blank=True,
null=True
)
last_used = models.DateTimeField(
verbose_name=_('last used'),
blank=True,
null=True
)
key = models.CharField(
verbose_name=_('key'),
max_length=40,
unique=True,
validators=[MinLengthValidator(40)]
)
write_enabled = models.BooleanField(
verbose_name=_('write enabled'),
default=True,
help_text=_('Permit create/update/delete operations using this key')
)
description = models.CharField(
verbose_name=_('description'),
max_length=200,
blank=True
)
@ -273,7 +280,7 @@ class Token(models.Model):
base_field=IPNetworkField(),
blank=True,
null=True,
verbose_name='Allowed IPs',
verbose_name=_('Allowed IPs'),
help_text=_(
'Allowed IPv4/IPv6 networks from where the token can be used. Leave blank for no restrictions. '
'Ex: "10.1.1.0/24, 192.168.10.16/32, 2001:DB8:1::/64"'
@ -344,13 +351,16 @@ class ObjectPermission(models.Model):
identified by ORM query parameters.
"""
name = models.CharField(
verbose_name=_('name'),
max_length=100
)
description = models.CharField(
verbose_name=_('description'),
max_length=200,
blank=True
)
enabled = models.BooleanField(
verbose_name=_('enabled'),
default=True
)
object_types = models.ManyToManyField(
@ -382,7 +392,7 @@ class ObjectPermission(models.Model):
class Meta:
ordering = ['name']
verbose_name = "permission"
verbose_name = _("permission")
def __str__(self):
return self.name

View File

@ -2,6 +2,7 @@ from django.contrib.contenttypes.fields import GenericRelation
from django.core.exceptions import ValidationError
from django.db import models
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from dcim.models import Device
from netbox.models import OrganizationalModel, PrimaryModel
@ -46,9 +47,11 @@ class Cluster(PrimaryModel):
A cluster of VirtualMachines. Each Cluster may optionally be associated with one or more Devices.
"""
name = models.CharField(
verbose_name=_('name'),
max_length=100
)
type = models.ForeignKey(
verbose_name=_('type'),
to=ClusterType,
on_delete=models.PROTECT,
related_name='clusters'
@ -61,6 +64,7 @@ class Cluster(PrimaryModel):
null=True
)
status = models.CharField(
verbose_name=_('status'),
max_length=50,
choices=ClusterStatusChoices,
default=ClusterStatusChoices.STATUS_ACTIVE
@ -128,7 +132,7 @@ class Cluster(PrimaryModel):
nonsite_devices = Device.objects.filter(cluster=self).exclude(site=self.site).count()
if nonsite_devices:
raise ValidationError({
'site': "{} devices are assigned as hosts for this cluster but are not in site {}".format(
'site': _("{} devices are assigned as hosts for this cluster but are not in site {}").format(
nonsite_devices, self.site
)
})

View File

@ -5,6 +5,7 @@ from django.db import models
from django.db.models import Q
from django.db.models.functions import Lower
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from dcim.models import BaseInterface
from extras.models import ConfigContextModel
@ -63,6 +64,7 @@ class VirtualMachine(PrimaryModel, ConfigContextModel):
null=True
)
name = models.CharField(
verbose_name=_('name'),
max_length=64
)
_name = NaturalOrderingField(
@ -74,7 +76,7 @@ class VirtualMachine(PrimaryModel, ConfigContextModel):
max_length=50,
choices=VirtualMachineStatusChoices,
default=VirtualMachineStatusChoices.STATUS_ACTIVE,
verbose_name='Status'
verbose_name=_('Status')
)
role = models.ForeignKey(
to='dcim.DeviceRole',
@ -113,12 +115,12 @@ class VirtualMachine(PrimaryModel, ConfigContextModel):
memory = models.PositiveIntegerField(
blank=True,
null=True,
verbose_name='Memory (MB)'
verbose_name=_('Memory (MB)')
)
disk = models.PositiveIntegerField(
blank=True,
null=True,
verbose_name='Disk (GB)'
verbose_name=_('Disk (GB)')
)
# Counter fields
@ -152,7 +154,7 @@ class VirtualMachine(PrimaryModel, ConfigContextModel):
Lower('name'), 'cluster',
name='%(app_label)s_%(class)s_unique_name_cluster',
condition=Q(tenant__isnull=True),
violation_error_message="Virtual machine name must be unique per cluster."
violation_error_message=_("Virtual machine name must be unique per cluster.")
),
)
@ -168,23 +170,23 @@ class VirtualMachine(PrimaryModel, ConfigContextModel):
# Must be assigned to a site and/or cluster
if not self.site and not self.cluster:
raise ValidationError({
'cluster': f'A virtual machine must be assigned to a site and/or cluster.'
'cluster': _('A virtual machine must be assigned to a site and/or cluster.')
})
# Validate site for cluster & device
if self.cluster and self.site and self.cluster.site != self.site:
raise ValidationError({
'cluster': f'The selected cluster ({self.cluster}) is not assigned to this site ({self.site}).'
'cluster': _('The selected cluster ({cluster}) is not assigned to this site ({site}).').format(cluster=self.cluster, site=self.site)
})
# Validate assigned cluster device
if self.device and not self.cluster:
raise ValidationError({
'device': f'Must specify a cluster when assigning a host device.'
'device': _('Must specify a cluster when assigning a host device.')
})
if self.device and self.device not in self.cluster.devices.all():
raise ValidationError({
'device': f'The selected device ({self.device}) is not assigned to this cluster ({self.cluster}).'
'device': _('The selected device ({device}) is not assigned to this cluster ({cluster}).').format(device=self.device, cluster=self.cluster)
})
# Validate primary IP addresses
@ -195,7 +197,8 @@ class VirtualMachine(PrimaryModel, ConfigContextModel):
if ip is not None:
if ip.address.version != family:
raise ValidationError({
field: f"Must be an IPv{family} address. ({ip} is an IPv{ip.address.version} address.)",
field: _("Must be an IPv{family} address. ({ip} is an IPv{version} address.)").format(
family=family, ip=ip, version=ip.address.version),
})
if ip.assigned_object in interfaces:
pass
@ -203,7 +206,7 @@ class VirtualMachine(PrimaryModel, ConfigContextModel):
pass
else:
raise ValidationError({
field: f"The specified IP address ({ip}) is not assigned to this VM.",
field: _("The specified IP address ({ip}) is not assigned to this VM.").format(ip=ip),
})
def save(self, *args, **kwargs):
@ -236,6 +239,7 @@ class VMInterface(NetBoxModel, BaseInterface, TrackingModelMixin):
related_name='interfaces'
)
name = models.CharField(
verbose_name=_('name'),
max_length=64
)
_name = NaturalOrderingField(
@ -245,6 +249,7 @@ class VMInterface(NetBoxModel, BaseInterface, TrackingModelMixin):
blank=True
)
description = models.CharField(
verbose_name=_('description'),
max_length=200,
blank=True
)
@ -254,13 +259,13 @@ class VMInterface(NetBoxModel, BaseInterface, TrackingModelMixin):
related_name='vminterfaces_as_untagged',
null=True,
blank=True,
verbose_name='Untagged VLAN'
verbose_name=_('Untagged VLAN')
)
tagged_vlans = models.ManyToManyField(
to='ipam.VLAN',
related_name='vminterfaces_as_tagged',
blank=True,
verbose_name='Tagged VLANs'
verbose_name=_('Tagged VLANs')
)
ip_addresses = GenericRelation(
to='ipam.IPAddress',
@ -274,7 +279,7 @@ class VMInterface(NetBoxModel, BaseInterface, TrackingModelMixin):
related_name='vminterfaces',
null=True,
blank=True,
verbose_name='VRF'
verbose_name=_('VRF')
)
fhrp_group_assignments = GenericRelation(
to='ipam.FHRPGroupAssignment',
@ -312,26 +317,26 @@ class VMInterface(NetBoxModel, BaseInterface, TrackingModelMixin):
# An interface cannot be its own parent
if self.pk and self.parent_id == self.pk:
raise ValidationError({'parent': "An interface cannot be its own parent."})
raise ValidationError({'parent': _("An interface cannot be its own parent.")})
# An interface's parent must belong to the same virtual machine
if self.parent and self.parent.virtual_machine != self.virtual_machine:
raise ValidationError({
'parent': f"The selected parent interface ({self.parent}) belongs to a different virtual machine "
f"({self.parent.virtual_machine})."
'parent': _("The selected parent interface ({parent}) belongs to a different virtual machine "
"({virtual_machine}).").format(parent=self.parent, virtual_machine=self.parent.virtual_machine)
})
# Bridge validation
# An interface cannot be bridged to itself
if self.pk and self.bridge_id == self.pk:
raise ValidationError({'bridge': "An interface cannot be bridged to itself."})
raise ValidationError({'bridge': _("An interface cannot be bridged to itself.")})
# A bridged interface belong to the same virtual machine
if self.bridge and self.bridge.virtual_machine != self.virtual_machine:
raise ValidationError({
'bridge': f"The selected bridge interface ({self.bridge}) belongs to a different virtual machine "
f"({self.bridge.virtual_machine})."
'bridge': _("The selected bridge interface ({bridge}) belongs to a different virtual machine "
"({virtual_machine}).").format(bridge=self.bridge, virtual_machine=self.bridge.virtual_machine)
})
# VLAN validation
@ -339,8 +344,8 @@ class VMInterface(NetBoxModel, BaseInterface, TrackingModelMixin):
# Validate untagged VLAN
if self.untagged_vlan and self.untagged_vlan.site not in [self.virtual_machine.site, None]:
raise ValidationError({
'untagged_vlan': f"The untagged VLAN ({self.untagged_vlan}) must belong to the same site as the "
f"interface's parent virtual machine, or it must be global."
'untagged_vlan': _("The untagged VLAN ({untagged_vlan}) must belong to the same site as the "
"interface's parent virtual machine, or it must be global.").format(untagged_vlan=self.untagged_vlan)
})
def to_objectchange(self, action):

View File

@ -1,6 +1,7 @@
from django.core.exceptions import ValidationError
from django.db import models
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from mptt.models import MPTTModel
from dcim.choices import LinkStatusChoices
@ -24,9 +25,10 @@ class WirelessAuthenticationBase(models.Model):
max_length=50,
choices=WirelessAuthTypeChoices,
blank=True,
verbose_name="Auth Type",
verbose_name=_("Auth Type"),
)
auth_cipher = models.CharField(
verbose_name=_('auth cipher'),
max_length=50,
choices=WirelessAuthCipherChoices,
blank=True
@ -34,7 +36,7 @@ class WirelessAuthenticationBase(models.Model):
auth_psk = models.CharField(
max_length=PSK_MAX_LENGTH,
blank=True,
verbose_name='Pre-shared key'
verbose_name=_('Pre-shared key')
)
class Meta:
@ -46,10 +48,12 @@ class WirelessLANGroup(NestedGroupModel):
A nested grouping of WirelessLANs
"""
name = models.CharField(
verbose_name=_('name'),
max_length=100,
unique=True
)
slug = models.SlugField(
verbose_name=_('slug'),
max_length=100,
unique=True
)
@ -74,7 +78,7 @@ class WirelessLAN(WirelessAuthenticationBase, PrimaryModel):
"""
ssid = models.CharField(
max_length=SSID_MAX_LENGTH,
verbose_name='SSID'
verbose_name=_('SSID')
)
group = models.ForeignKey(
to='wireless.WirelessLANGroup',
@ -93,7 +97,7 @@ class WirelessLAN(WirelessAuthenticationBase, PrimaryModel):
on_delete=models.PROTECT,
blank=True,
null=True,
verbose_name='VLAN'
verbose_name=_('VLAN')
)
tenant = models.ForeignKey(
to='tenancy.Tenant',
@ -134,21 +138,22 @@ class WirelessLink(WirelessAuthenticationBase, PrimaryModel):
limit_choices_to=get_wireless_interface_types,
on_delete=models.PROTECT,
related_name='+',
verbose_name="Interface A",
verbose_name=_('Interface A'),
)
interface_b = models.ForeignKey(
to='dcim.Interface',
limit_choices_to=get_wireless_interface_types,
on_delete=models.PROTECT,
related_name='+',
verbose_name="Interface B",
verbose_name=_('Interface B'),
)
ssid = models.CharField(
max_length=SSID_MAX_LENGTH,
blank=True,
verbose_name='SSID'
verbose_name=_('SSID')
)
status = models.CharField(
verbose_name=_('status'),
max_length=50,
choices=LinkStatusChoices,
default=LinkStatusChoices.STATUS_CONNECTED
@ -203,11 +208,11 @@ class WirelessLink(WirelessAuthenticationBase, PrimaryModel):
# Validate interface types
if self.interface_a.type not in WIRELESS_IFACE_TYPES:
raise ValidationError({
'interface_a': f"{self.interface_a.get_type_display()} is not a wireless interface."
'interface_a': _("{type_display} is not a wireless interface.").format(type_display=self.interface_a.get_type_display())
})
if self.interface_b.type not in WIRELESS_IFACE_TYPES:
raise ValidationError({
'interface_a': f"{self.interface_b.get_type_display()} is not a wireless interface."
'interface_a': _("{type_display} is not a wireless interface.").format(type_display=self.interface_b.get_type_display())
})
def save(self, *args, **kwargs):