diff --git a/.github/workflows/close-stale-issues.yml b/.github/workflows/close-stale-issues.yml index 29f28fddf..1e0e193df 100644 --- a/.github/workflows/close-stale-issues.yml +++ b/.github/workflows/close-stale-issues.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/stale@v9 with: # General parameters - operations-per-run: 100 + operations-per-run: 200 remove-stale-when-updated: false # Issue parameters @@ -43,7 +43,7 @@ jobs: # Pull request parameters close-pr-message: > This PR has been automatically closed due to lack of activity. - days-before-pr-stale: 15 + days-before-pr-stale: 30 days-before-pr-close: 15 exempt-pr-labels: 'status: blocked' stale-pr-label: 'pending closure' diff --git a/docs/_theme/partials/copyright.html b/docs/_theme/partials/copyright.html new file mode 100644 index 000000000..cfbfd5444 --- /dev/null +++ b/docs/_theme/partials/copyright.html @@ -0,0 +1,18 @@ + +{% if not config.extra.build_public %} + +{% endif %} diff --git a/netbox/core/management/commands/nbshell.py b/netbox/core/management/commands/nbshell.py index e26f956c8..8f729d10a 100644 --- a/netbox/core/management/commands/nbshell.py +++ b/netbox/core/management/commands/nbshell.py @@ -11,6 +11,10 @@ from core.models import ObjectType from users.models import User APPS = ('circuits', 'core', 'dcim', 'extras', 'ipam', 'tenancy', 'users', 'virtualization', 'vpn', 'wireless') +EXCLUDE_MODELS = ( + 'extras.branch', + 'extras.stagedchange', +) BANNER_TEXT = """### NetBox interactive shell ({node}) ### Python {python} | Django {django} | NetBox {netbox} @@ -44,12 +48,16 @@ class Command(BaseCommand): # Gather Django models and constants from each app for app in APPS: - self.django_models[app] = [] + models = [] # Load models from each app for model in apps.get_app_config(app).get_models(): - namespace[model.__name__] = model - self.django_models[app].append(model.__name__) + app_label = model._meta.app_label + model_name = model._meta.model_name + if f'{app_label}.{model_name}' not in EXCLUDE_MODELS: + namespace[model.__name__] = model + models.append(model.__name__) + self.django_models[app] = sorted(models) # Constants try: diff --git a/netbox/dcim/choices.py b/netbox/dcim/choices.py index 974ea4024..53c3bced9 100644 --- a/netbox/dcim/choices.py +++ b/netbox/dcim/choices.py @@ -685,6 +685,7 @@ class PowerOutletTypeChoices(ChoiceSet): # Direct current (DC) TYPE_DC = 'dc-terminal' # Proprietary + TYPE_EATON_C39 = 'eaton-c39' TYPE_HDOT_CX = 'hdot-cx' TYPE_SAF_D_GRID = 'saf-d-grid' TYPE_NEUTRIK_POWERCON_20A = 'neutrik-powercon-20a' @@ -806,6 +807,7 @@ class PowerOutletTypeChoices(ChoiceSet): (TYPE_DC, 'DC Terminal'), )), (_('Proprietary'), ( + (TYPE_EATON_C39, 'Eaton C39'), (TYPE_HDOT_CX, 'HDOT Cx'), (TYPE_SAF_D_GRID, 'Saf-D-Grid'), (TYPE_NEUTRIK_POWERCON_20A, 'Neutrik powerCON (20A)'), diff --git a/netbox/extras/models/customfields.py b/netbox/extras/models/customfields.py index 7a0a08614..889594902 100644 --- a/netbox/extras/models/customfields.py +++ b/netbox/extras/models/customfields.py @@ -294,11 +294,11 @@ class CustomField(CloningMixin, ExportTemplatesMixin, ChangeLoggedModel): no longer assigned to a model, or because it has been deleted). """ for ct in content_types: - model = ct.model_class() - instances = model.objects.filter(custom_field_data__has_key=self.name) - for instance in instances: - del instance.custom_field_data[self.name] - model.objects.bulk_update(instances, ['custom_field_data'], batch_size=100) + if model := ct.model_class(): + instances = model.objects.filter(custom_field_data__has_key=self.name) + for instance in instances: + del instance.custom_field_data[self.name] + model.objects.bulk_update(instances, ['custom_field_data'], batch_size=100) def rename_object_data(self, old_name, new_name): """ diff --git a/netbox/netbox/api/serializers/fields.py b/netbox/netbox/api/serializers/fields.py index 4fee36043..74782bddf 100644 --- a/netbox/netbox/api/serializers/fields.py +++ b/netbox/netbox/api/serializers/fields.py @@ -1,5 +1,8 @@ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers +from utilities.views import get_viewname + __all__ = ( 'NetBoxAPIHyperlinkedIdentityField', 'NetBoxURLHyperlinkedIdentityField', @@ -30,12 +33,10 @@ class BaseNetBoxHyperlinkedIdentityField(serializers.HyperlinkedIdentityField): lookup_value = getattr(obj, self.lookup_field) kwargs = {self.lookup_url_kwarg: lookup_value} - model_name = self.parent.Meta.model._meta.model_name - app_name = self.parent.Meta.model._meta.app_label - view_name = self.get_view_name(app_name, model_name) + view_name = self.get_view_name(obj) return self.reverse(view_name, kwargs=kwargs, request=request, format=format) - def get_view_name(self, app_name, model_name): + def get_view_name(self, model): raise NotImplementedError(_('{class_name} must implement get_view_name()').format( class_name=self.__class__.__name__ )) @@ -43,11 +44,11 @@ class BaseNetBoxHyperlinkedIdentityField(serializers.HyperlinkedIdentityField): class NetBoxAPIHyperlinkedIdentityField(BaseNetBoxHyperlinkedIdentityField): - def get_view_name(self, app_name, model_name): - return f'{app_name}-api:{model_name}-detail' + def get_view_name(self, model): + return get_viewname(model=model, action='detail', rest_api=True) class NetBoxURLHyperlinkedIdentityField(BaseNetBoxHyperlinkedIdentityField): - def get_view_name(self, app_name, model_name): - return f'{app_name}:{model_name}' + def get_view_name(self, model): + return get_viewname(model=model) diff --git a/netbox/project-static/dist/netbox.css b/netbox/project-static/dist/netbox.css index 762cafd5d..f1b9e24e2 100644 Binary files a/netbox/project-static/dist/netbox.css and b/netbox/project-static/dist/netbox.css differ diff --git a/netbox/project-static/package.json b/netbox/project-static/package.json index acc6803b6..5c16bee60 100644 --- a/netbox/project-static/package.json +++ b/netbox/project-static/package.json @@ -24,7 +24,7 @@ "dependencies": { "@fontsource-variable/plus-jakarta-sans": "^5.1.0", "@mdi/font": "7.4.47", - "@tabler/core": "1.0.0-beta20", + "@tabler/core": "1.0.0-beta21", "bootstrap": "5.3.3", "clipboard": "2.0.11", "flatpickr": "4.6.13", diff --git a/netbox/project-static/yarn.lock b/netbox/project-static/yarn.lock index bc1f541b2..ca9f5ff96 100644 --- a/netbox/project-static/yarn.lock +++ b/netbox/project-static/yarn.lock @@ -675,19 +675,19 @@ resolved "https://registry.yarnpkg.com/@rtsao/scc/-/scc-1.1.0.tgz#927dd2fae9bc3361403ac2c7a00c32ddce9ad7e8" integrity sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g== -"@tabler/core@1.0.0-beta20": - version "1.0.0-beta20" - resolved "https://registry.yarnpkg.com/@tabler/core/-/core-1.0.0-beta20.tgz#3fcc3b5634ca89a413ba9c077df7bdfc531ab93c" - integrity sha512-OzKpur+Ug7e+HMbNJrMcSuWZGUsJTvu7HYboBNRE8qyo1RKIWqvwL5YewKBJ+odW5pDOqBPzbsS4je3EBQQxHw== +"@tabler/core@1.0.0-beta21": + version "1.0.0-beta21" + resolved "https://registry.yarnpkg.com/@tabler/core/-/core-1.0.0-beta21.tgz#cd10d7648b3b7b31927a430fd776d3304e796403" + integrity sha512-9ZKu38BScc0eHruhX/SlVDSiXenBFSgBp2WDq6orkuC8J/1yutKDt7CdXuJpBwkiADEk5yqYV31Ku+CnhwOc3Q== dependencies: "@popperjs/core" "^2.11.8" - "@tabler/icons" "^2.32.0" - bootstrap "5.3.1" + "@tabler/icons" "^3.14.0" + bootstrap "5.3.3" -"@tabler/icons@^2.32.0": - version "2.47.0" - resolved "https://registry.yarnpkg.com/@tabler/icons/-/icons-2.47.0.tgz#c41c680d1947e3ab2d60af3febc4132287c60596" - integrity sha512-4w5evLh+7FUUiA1GucvGj2ReX2TvOjEr4ejXdwL/bsjoSkof6r1gQmzqI+VHrE2CpJpB3al7bCTulOkFa/RcyA== +"@tabler/icons@^3.14.0": + version "3.16.0" + resolved "https://registry.yarnpkg.com/@tabler/icons/-/icons-3.16.0.tgz#d618670b80163925a31a6c2290e8775f6058d81a" + integrity sha512-GU7MSx4uQEr55BmyON6hD/QYTl6k1v0YlRhM91gBWDoKAbyCt6QIYw7rpJ/ecdh5zrHaTOJKPenZ4+luoutwFA== "@tanstack/react-virtual@^3.0.0-beta.60": version "3.5.0" @@ -977,11 +977,6 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== -bootstrap@5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.3.1.tgz#8ca07040ad15d7f75891d1504cf14c5dedfb1cfe" - integrity sha512-jzwza3Yagduci2x0rr9MeFSORjcHpt0lRZukZPZQJT1Dth5qzV7XcgGqYzi39KGAVYR8QEDVoO0ubFKOxzMG+g== - bootstrap@5.3.3: version "5.3.3" resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.3.3.tgz#de35e1a765c897ac940021900fcbb831602bac38" diff --git a/netbox/translations/en/LC_MESSAGES/django.po b/netbox/translations/en/LC_MESSAGES/django.po index a49ec7322..a7f568256 100644 --- a/netbox/translations/en/LC_MESSAGES/django.po +++ b/netbox/translations/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-09-12 05:02+0000\n" +"POT-Creation-Date: 2024-09-18 05:02+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -82,8 +82,8 @@ msgstr "" #: netbox/circuits/choices.py:21 netbox/dcim/choices.py:20 #: netbox/dcim/choices.py:102 netbox/dcim/choices.py:185 -#: netbox/dcim/choices.py:231 netbox/dcim/choices.py:1518 -#: netbox/dcim/choices.py:1594 netbox/dcim/choices.py:1644 +#: netbox/dcim/choices.py:231 netbox/dcim/choices.py:1520 +#: netbox/dcim/choices.py:1596 netbox/dcim/choices.py:1646 #: netbox/virtualization/choices.py:20 netbox/virtualization/choices.py:45 #: netbox/vpn/choices.py:18 msgid "Planned" @@ -96,7 +96,7 @@ msgstr "" #: netbox/circuits/choices.py:23 netbox/core/tables/tasks.py:22 #: netbox/dcim/choices.py:22 netbox/dcim/choices.py:103 #: netbox/dcim/choices.py:184 netbox/dcim/choices.py:230 -#: netbox/dcim/choices.py:1593 netbox/dcim/choices.py:1643 +#: netbox/dcim/choices.py:1595 netbox/dcim/choices.py:1645 #: netbox/extras/tables/tables.py:495 netbox/ipam/choices.py:31 #: netbox/ipam/choices.py:49 netbox/ipam/choices.py:69 #: netbox/ipam/choices.py:154 netbox/templates/extras/configcontext.html:25 @@ -107,8 +107,8 @@ msgid "Active" msgstr "" #: netbox/circuits/choices.py:24 netbox/dcim/choices.py:183 -#: netbox/dcim/choices.py:229 netbox/dcim/choices.py:1592 -#: netbox/dcim/choices.py:1645 netbox/virtualization/choices.py:24 +#: netbox/dcim/choices.py:229 netbox/dcim/choices.py:1594 +#: netbox/dcim/choices.py:1647 netbox/virtualization/choices.py:24 #: netbox/virtualization/choices.py:43 msgid "Offline" msgstr "" @@ -121,7 +121,7 @@ msgstr "" msgid "Decommissioned" msgstr "" -#: netbox/circuits/choices.py:90 netbox/dcim/choices.py:1605 +#: netbox/circuits/choices.py:90 netbox/dcim/choices.py:1607 #: netbox/tenancy/choices.py:17 msgid "Primary" msgstr "" @@ -1587,7 +1587,7 @@ msgstr "" #: netbox/core/choices.py:22 netbox/core/choices.py:59 #: netbox/core/constants.py:20 netbox/core/tables/tasks.py:34 #: netbox/dcim/choices.py:187 netbox/dcim/choices.py:233 -#: netbox/dcim/choices.py:1595 netbox/virtualization/choices.py:47 +#: netbox/dcim/choices.py:1597 netbox/virtualization/choices.py:47 msgid "Failed" msgstr "" @@ -1911,7 +1911,7 @@ msgstr "" msgid "Rack Elevations" msgstr "" -#: netbox/core/forms/model_forms.py:157 netbox/dcim/choices.py:1506 +#: netbox/core/forms/model_forms.py:157 netbox/dcim/choices.py:1508 #: netbox/dcim/forms/bulk_edit.py:969 netbox/dcim/forms/bulk_edit.py:1357 #: netbox/dcim/forms/bulk_edit.py:1375 netbox/dcim/tables/racks.py:158 #: netbox/netbox/navigation/menu.py:291 netbox/netbox/navigation/menu.py:295 @@ -2477,7 +2477,7 @@ msgid "Staging" msgstr "" #: netbox/dcim/choices.py:23 netbox/dcim/choices.py:189 -#: netbox/dcim/choices.py:234 netbox/dcim/choices.py:1519 +#: netbox/dcim/choices.py:234 netbox/dcim/choices.py:1521 #: netbox/virtualization/choices.py:23 netbox/virtualization/choices.py:48 msgid "Decommissioning" msgstr "" @@ -2541,7 +2541,7 @@ msgstr "" msgid "Millimeters" msgstr "" -#: netbox/dcim/choices.py:115 netbox/dcim/choices.py:1541 +#: netbox/dcim/choices.py:115 netbox/dcim/choices.py:1543 msgid "Inches" msgstr "" @@ -2630,7 +2630,7 @@ msgid "Side to rear" msgstr "" #: netbox/dcim/choices.py:209 netbox/dcim/choices.py:253 -#: netbox/dcim/choices.py:1291 +#: netbox/dcim/choices.py:1293 msgid "Passive" msgstr "" @@ -2638,15 +2638,15 @@ msgstr "" msgid "Mixed" msgstr "" -#: netbox/dcim/choices.py:478 netbox/dcim/choices.py:726 +#: netbox/dcim/choices.py:478 netbox/dcim/choices.py:727 msgid "NEMA (Non-locking)" msgstr "" -#: netbox/dcim/choices.py:500 netbox/dcim/choices.py:748 +#: netbox/dcim/choices.py:500 netbox/dcim/choices.py:749 msgid "NEMA (Locking)" msgstr "" -#: netbox/dcim/choices.py:524 netbox/dcim/choices.py:772 +#: netbox/dcim/choices.py:524 netbox/dcim/choices.py:773 msgid "California Style" msgstr "" @@ -2654,30 +2654,30 @@ msgstr "" msgid "International/ITA" msgstr "" -#: netbox/dcim/choices.py:567 netbox/dcim/choices.py:807 +#: netbox/dcim/choices.py:567 netbox/dcim/choices.py:808 msgid "Proprietary" msgstr "" -#: netbox/dcim/choices.py:575 netbox/dcim/choices.py:816 -#: netbox/dcim/choices.py:1207 netbox/dcim/choices.py:1209 -#: netbox/dcim/choices.py:1435 netbox/dcim/choices.py:1437 +#: netbox/dcim/choices.py:575 netbox/dcim/choices.py:818 +#: netbox/dcim/choices.py:1209 netbox/dcim/choices.py:1211 +#: netbox/dcim/choices.py:1437 netbox/dcim/choices.py:1439 #: netbox/netbox/navigation/menu.py:200 msgid "Other" msgstr "" -#: netbox/dcim/choices.py:780 +#: netbox/dcim/choices.py:781 msgid "ITA/International" msgstr "" -#: netbox/dcim/choices.py:846 +#: netbox/dcim/choices.py:848 msgid "Physical" msgstr "" -#: netbox/dcim/choices.py:847 netbox/dcim/choices.py:1013 +#: netbox/dcim/choices.py:849 netbox/dcim/choices.py:1015 msgid "Virtual" msgstr "" -#: netbox/dcim/choices.py:848 netbox/dcim/choices.py:1086 +#: netbox/dcim/choices.py:850 netbox/dcim/choices.py:1088 #: netbox/dcim/forms/bulk_edit.py:1515 netbox/dcim/forms/filtersets.py:1330 #: netbox/dcim/forms/model_forms.py:988 netbox/dcim/forms/model_forms.py:1396 #: netbox/netbox/navigation/menu.py:140 netbox/netbox/navigation/menu.py:144 @@ -2685,11 +2685,11 @@ msgstr "" msgid "Wireless" msgstr "" -#: netbox/dcim/choices.py:1011 +#: netbox/dcim/choices.py:1013 msgid "Virtual interfaces" msgstr "" -#: netbox/dcim/choices.py:1014 netbox/dcim/forms/bulk_edit.py:1410 +#: netbox/dcim/choices.py:1016 netbox/dcim/forms/bulk_edit.py:1410 #: netbox/dcim/forms/bulk_import.py:840 netbox/dcim/forms/model_forms.py:974 #: netbox/dcim/tables/devices.py:657 netbox/templates/dcim/interface.html:106 #: netbox/templates/virtualization/vminterface.html:43 @@ -2699,27 +2699,27 @@ msgstr "" msgid "Bridge" msgstr "" -#: netbox/dcim/choices.py:1015 +#: netbox/dcim/choices.py:1017 msgid "Link Aggregation Group (LAG)" msgstr "" -#: netbox/dcim/choices.py:1019 +#: netbox/dcim/choices.py:1021 msgid "Ethernet (fixed)" msgstr "" -#: netbox/dcim/choices.py:1034 +#: netbox/dcim/choices.py:1036 msgid "Ethernet (modular)" msgstr "" -#: netbox/dcim/choices.py:1070 +#: netbox/dcim/choices.py:1072 msgid "Ethernet (backplane)" msgstr "" -#: netbox/dcim/choices.py:1101 +#: netbox/dcim/choices.py:1103 msgid "Cellular" msgstr "" -#: netbox/dcim/choices.py:1153 netbox/dcim/forms/filtersets.py:383 +#: netbox/dcim/choices.py:1155 netbox/dcim/forms/filtersets.py:383 #: netbox/dcim/forms/filtersets.py:809 netbox/dcim/forms/filtersets.py:963 #: netbox/dcim/forms/filtersets.py:1542 #: netbox/templates/dcim/inventoryitem.html:52 @@ -2727,129 +2727,129 @@ msgstr "" msgid "Serial" msgstr "" -#: netbox/dcim/choices.py:1168 +#: netbox/dcim/choices.py:1170 msgid "Coaxial" msgstr "" -#: netbox/dcim/choices.py:1188 +#: netbox/dcim/choices.py:1190 msgid "Stacking" msgstr "" -#: netbox/dcim/choices.py:1238 +#: netbox/dcim/choices.py:1240 msgid "Half" msgstr "" -#: netbox/dcim/choices.py:1239 +#: netbox/dcim/choices.py:1241 msgid "Full" msgstr "" -#: netbox/dcim/choices.py:1240 netbox/netbox/preferences.py:31 +#: netbox/dcim/choices.py:1242 netbox/netbox/preferences.py:31 #: netbox/wireless/choices.py:480 msgid "Auto" msgstr "" -#: netbox/dcim/choices.py:1251 +#: netbox/dcim/choices.py:1253 msgid "Access" msgstr "" -#: netbox/dcim/choices.py:1252 netbox/ipam/tables/vlans.py:172 +#: netbox/dcim/choices.py:1254 netbox/ipam/tables/vlans.py:172 #: netbox/ipam/tables/vlans.py:217 #: netbox/templates/dcim/inc/interface_vlans_table.html:7 msgid "Tagged" msgstr "" -#: netbox/dcim/choices.py:1253 +#: netbox/dcim/choices.py:1255 msgid "Tagged (All)" msgstr "" -#: netbox/dcim/choices.py:1282 +#: netbox/dcim/choices.py:1284 msgid "IEEE Standard" msgstr "" -#: netbox/dcim/choices.py:1293 +#: netbox/dcim/choices.py:1295 msgid "Passive 24V (2-pair)" msgstr "" -#: netbox/dcim/choices.py:1294 +#: netbox/dcim/choices.py:1296 msgid "Passive 24V (4-pair)" msgstr "" -#: netbox/dcim/choices.py:1295 +#: netbox/dcim/choices.py:1297 msgid "Passive 48V (2-pair)" msgstr "" -#: netbox/dcim/choices.py:1296 +#: netbox/dcim/choices.py:1298 msgid "Passive 48V (4-pair)" msgstr "" -#: netbox/dcim/choices.py:1366 netbox/dcim/choices.py:1476 +#: netbox/dcim/choices.py:1368 netbox/dcim/choices.py:1478 msgid "Copper" msgstr "" -#: netbox/dcim/choices.py:1389 +#: netbox/dcim/choices.py:1391 msgid "Fiber Optic" msgstr "" -#: netbox/dcim/choices.py:1422 netbox/dcim/choices.py:1505 +#: netbox/dcim/choices.py:1424 netbox/dcim/choices.py:1507 msgid "USB" msgstr "" -#: netbox/dcim/choices.py:1492 +#: netbox/dcim/choices.py:1494 msgid "Fiber" msgstr "" -#: netbox/dcim/choices.py:1517 netbox/dcim/forms/filtersets.py:1227 +#: netbox/dcim/choices.py:1519 netbox/dcim/forms/filtersets.py:1227 msgid "Connected" msgstr "" -#: netbox/dcim/choices.py:1536 netbox/wireless/choices.py:497 +#: netbox/dcim/choices.py:1538 netbox/wireless/choices.py:497 msgid "Kilometers" msgstr "" -#: netbox/dcim/choices.py:1537 netbox/templates/dcim/cable_trace.html:65 +#: netbox/dcim/choices.py:1539 netbox/templates/dcim/cable_trace.html:65 #: netbox/wireless/choices.py:498 msgid "Meters" msgstr "" -#: netbox/dcim/choices.py:1538 +#: netbox/dcim/choices.py:1540 msgid "Centimeters" msgstr "" -#: netbox/dcim/choices.py:1539 netbox/wireless/choices.py:499 +#: netbox/dcim/choices.py:1541 netbox/wireless/choices.py:499 msgid "Miles" msgstr "" -#: netbox/dcim/choices.py:1540 netbox/templates/dcim/cable_trace.html:66 +#: netbox/dcim/choices.py:1542 netbox/templates/dcim/cable_trace.html:66 #: netbox/wireless/choices.py:500 msgid "Feet" msgstr "" -#: netbox/dcim/choices.py:1556 netbox/templates/dcim/device.html:327 +#: netbox/dcim/choices.py:1558 netbox/templates/dcim/device.html:327 #: netbox/templates/dcim/rack.html:106 msgid "Kilograms" msgstr "" -#: netbox/dcim/choices.py:1557 +#: netbox/dcim/choices.py:1559 msgid "Grams" msgstr "" -#: netbox/dcim/choices.py:1558 netbox/templates/dcim/rack.html:107 +#: netbox/dcim/choices.py:1560 netbox/templates/dcim/rack.html:107 msgid "Pounds" msgstr "" -#: netbox/dcim/choices.py:1559 +#: netbox/dcim/choices.py:1561 msgid "Ounces" msgstr "" -#: netbox/dcim/choices.py:1606 +#: netbox/dcim/choices.py:1608 msgid "Redundant" msgstr "" -#: netbox/dcim/choices.py:1627 +#: netbox/dcim/choices.py:1629 msgid "Single phase" msgstr "" -#: netbox/dcim/choices.py:1628 +#: netbox/dcim/choices.py:1630 msgid "Three-phase" msgstr "" @@ -10097,7 +10097,7 @@ msgstr "" msgid "Range boundaries must be defined as integers." msgstr "" -#: netbox/netbox/api/serializers/fields.py:39 +#: netbox/netbox/api/serializers/fields.py:40 #, python-brace-format msgid "{class_name} must implement get_view_name()" msgstr ""