mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
10300 initial translation support use gettext
This commit is contained in:
@@ -2,6 +2,7 @@ import django_filters
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.db.models import Q
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
from dcim.models import DeviceRole, DeviceType, Location, Platform, Region, Site, SiteGroup
|
||||
from netbox.filtersets import BaseFilterSet, ChangeLoggedModelFilterSet, NetBoxModelFilterSet
|
||||
@@ -32,7 +33,7 @@ __all__ = (
|
||||
class WebhookFilterSet(BaseFilterSet):
|
||||
q = django_filters.CharFilter(
|
||||
method='search',
|
||||
label='Search',
|
||||
label=_('Search'),
|
||||
)
|
||||
content_type_id = MultiValueNumberFilter(
|
||||
field_name='content_types__id'
|
||||
@@ -61,7 +62,7 @@ class WebhookFilterSet(BaseFilterSet):
|
||||
class CustomFieldFilterSet(BaseFilterSet):
|
||||
q = django_filters.CharFilter(
|
||||
method='search',
|
||||
label='Search',
|
||||
label=_('Search'),
|
||||
)
|
||||
type = django_filters.MultipleChoiceFilter(
|
||||
choices=CustomFieldTypeChoices
|
||||
@@ -92,7 +93,7 @@ class CustomFieldFilterSet(BaseFilterSet):
|
||||
class CustomLinkFilterSet(BaseFilterSet):
|
||||
q = django_filters.CharFilter(
|
||||
method='search',
|
||||
label='Search',
|
||||
label=_('Search'),
|
||||
)
|
||||
content_type_id = MultiValueNumberFilter(
|
||||
field_name='content_types__id'
|
||||
@@ -119,7 +120,7 @@ class CustomLinkFilterSet(BaseFilterSet):
|
||||
class ExportTemplateFilterSet(BaseFilterSet):
|
||||
q = django_filters.CharFilter(
|
||||
method='search',
|
||||
label='Search',
|
||||
label=_('Search'),
|
||||
)
|
||||
content_type_id = MultiValueNumberFilter(
|
||||
field_name='content_types__id'
|
||||
@@ -142,7 +143,7 @@ class ExportTemplateFilterSet(BaseFilterSet):
|
||||
class SavedFilterFilterSet(BaseFilterSet):
|
||||
q = django_filters.CharFilter(
|
||||
method='search',
|
||||
label='Search',
|
||||
label=_('Search'),
|
||||
)
|
||||
content_type_id = MultiValueNumberFilter(
|
||||
field_name='content_types__id'
|
||||
@@ -150,13 +151,13 @@ class SavedFilterFilterSet(BaseFilterSet):
|
||||
content_types = ContentTypeFilter()
|
||||
user_id = django_filters.ModelMultipleChoiceFilter(
|
||||
queryset=User.objects.all(),
|
||||
label='User (ID)',
|
||||
label=_('User (ID)'),
|
||||
)
|
||||
user = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='user__username',
|
||||
queryset=User.objects.all(),
|
||||
to_field_name='username',
|
||||
label='User (name)',
|
||||
label=_('User (name)'),
|
||||
)
|
||||
usable = django_filters.BooleanFilter(
|
||||
method='_usable'
|
||||
@@ -191,7 +192,7 @@ class SavedFilterFilterSet(BaseFilterSet):
|
||||
class ImageAttachmentFilterSet(BaseFilterSet):
|
||||
q = django_filters.CharFilter(
|
||||
method='search',
|
||||
label='Search',
|
||||
label=_('Search'),
|
||||
)
|
||||
created = django_filters.DateTimeFilter()
|
||||
content_type = ContentTypeFilter()
|
||||
@@ -211,13 +212,13 @@ class JournalEntryFilterSet(NetBoxModelFilterSet):
|
||||
assigned_object_type = ContentTypeFilter()
|
||||
created_by_id = django_filters.ModelMultipleChoiceFilter(
|
||||
queryset=User.objects.all(),
|
||||
label='User (ID)',
|
||||
label=_('User (ID)'),
|
||||
)
|
||||
created_by = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='created_by__username',
|
||||
queryset=User.objects.all(),
|
||||
to_field_name='username',
|
||||
label='User (name)',
|
||||
label=_('User (name)'),
|
||||
)
|
||||
kind = django_filters.MultipleChoiceFilter(
|
||||
choices=JournalEntryKindChoices
|
||||
@@ -236,7 +237,7 @@ class JournalEntryFilterSet(NetBoxModelFilterSet):
|
||||
class TagFilterSet(ChangeLoggedModelFilterSet):
|
||||
q = django_filters.CharFilter(
|
||||
method='search',
|
||||
label='Search',
|
||||
label=_('Search'),
|
||||
)
|
||||
content_type = MultiValueCharFilter(
|
||||
method='_content_type'
|
||||
@@ -288,138 +289,138 @@ class TagFilterSet(ChangeLoggedModelFilterSet):
|
||||
class ConfigContextFilterSet(ChangeLoggedModelFilterSet):
|
||||
q = django_filters.CharFilter(
|
||||
method='search',
|
||||
label='Search',
|
||||
label=_('Search'),
|
||||
)
|
||||
region_id = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='regions',
|
||||
queryset=Region.objects.all(),
|
||||
label='Region',
|
||||
label=_('Region'),
|
||||
)
|
||||
region = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='regions__slug',
|
||||
queryset=Region.objects.all(),
|
||||
to_field_name='slug',
|
||||
label='Region (slug)',
|
||||
label=_('Region (slug)'),
|
||||
)
|
||||
site_group = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='site_groups__slug',
|
||||
queryset=SiteGroup.objects.all(),
|
||||
to_field_name='slug',
|
||||
label='Site group (slug)',
|
||||
label=_('Site group (slug)'),
|
||||
)
|
||||
site_group_id = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='site_groups',
|
||||
queryset=SiteGroup.objects.all(),
|
||||
label='Site group',
|
||||
label=_('Site group'),
|
||||
)
|
||||
site_id = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='sites',
|
||||
queryset=Site.objects.all(),
|
||||
label='Site',
|
||||
label=_('Site'),
|
||||
)
|
||||
site = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='sites__slug',
|
||||
queryset=Site.objects.all(),
|
||||
to_field_name='slug',
|
||||
label='Site (slug)',
|
||||
label=_('Site (slug)'),
|
||||
)
|
||||
location_id = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='locations',
|
||||
queryset=Location.objects.all(),
|
||||
label='Location',
|
||||
label=_('Location'),
|
||||
)
|
||||
location = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='locations__slug',
|
||||
queryset=Location.objects.all(),
|
||||
to_field_name='slug',
|
||||
label='Location (slug)',
|
||||
label=_('Location (slug)'),
|
||||
)
|
||||
device_type_id = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='device_types',
|
||||
queryset=DeviceType.objects.all(),
|
||||
label='Device type',
|
||||
label=_('Device type'),
|
||||
)
|
||||
role_id = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='roles',
|
||||
queryset=DeviceRole.objects.all(),
|
||||
label='Role',
|
||||
label=_('Role'),
|
||||
)
|
||||
role = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='roles__slug',
|
||||
queryset=DeviceRole.objects.all(),
|
||||
to_field_name='slug',
|
||||
label='Role (slug)',
|
||||
label=_('Role (slug)'),
|
||||
)
|
||||
platform_id = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='platforms',
|
||||
queryset=Platform.objects.all(),
|
||||
label='Platform',
|
||||
label=_('Platform'),
|
||||
)
|
||||
platform = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='platforms__slug',
|
||||
queryset=Platform.objects.all(),
|
||||
to_field_name='slug',
|
||||
label='Platform (slug)',
|
||||
label=_('Platform (slug)'),
|
||||
)
|
||||
cluster_type_id = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='cluster_types',
|
||||
queryset=ClusterType.objects.all(),
|
||||
label='Cluster type',
|
||||
label=_('Cluster type'),
|
||||
)
|
||||
cluster_type = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='cluster_types__slug',
|
||||
queryset=ClusterType.objects.all(),
|
||||
to_field_name='slug',
|
||||
label='Cluster type (slug)',
|
||||
label=_('Cluster type (slug)'),
|
||||
)
|
||||
cluster_group_id = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='cluster_groups',
|
||||
queryset=ClusterGroup.objects.all(),
|
||||
label='Cluster group',
|
||||
label=_('Cluster group'),
|
||||
)
|
||||
cluster_group = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='cluster_groups__slug',
|
||||
queryset=ClusterGroup.objects.all(),
|
||||
to_field_name='slug',
|
||||
label='Cluster group (slug)',
|
||||
label=_('Cluster group (slug)'),
|
||||
)
|
||||
cluster_id = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='clusters',
|
||||
queryset=Cluster.objects.all(),
|
||||
label='Cluster',
|
||||
label=_('Cluster'),
|
||||
)
|
||||
tenant_group_id = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='tenant_groups',
|
||||
queryset=TenantGroup.objects.all(),
|
||||
label='Tenant group',
|
||||
label=_('Tenant group'),
|
||||
)
|
||||
tenant_group = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='tenant_groups__slug',
|
||||
queryset=TenantGroup.objects.all(),
|
||||
to_field_name='slug',
|
||||
label='Tenant group (slug)',
|
||||
label=_('Tenant group (slug)'),
|
||||
)
|
||||
tenant_id = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='tenants',
|
||||
queryset=Tenant.objects.all(),
|
||||
label='Tenant',
|
||||
label=_('Tenant'),
|
||||
)
|
||||
tenant = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='tenants__slug',
|
||||
queryset=Tenant.objects.all(),
|
||||
to_field_name='slug',
|
||||
label='Tenant (slug)',
|
||||
label=_('Tenant (slug)'),
|
||||
)
|
||||
tag_id = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='tags',
|
||||
queryset=Tag.objects.all(),
|
||||
label='Tag',
|
||||
label=_('Tag'),
|
||||
)
|
||||
tag = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='tags__slug',
|
||||
queryset=Tag.objects.all(),
|
||||
to_field_name='slug',
|
||||
label='Tag (slug)',
|
||||
label=_('Tag (slug)'),
|
||||
)
|
||||
|
||||
class Meta:
|
||||
@@ -443,7 +444,7 @@ class ConfigContextFilterSet(ChangeLoggedModelFilterSet):
|
||||
class LocalConfigContextFilterSet(django_filters.FilterSet):
|
||||
local_context_data = django_filters.BooleanFilter(
|
||||
method='_local_context_data',
|
||||
label='Has local config context data',
|
||||
label=_('Has local config context data'),
|
||||
)
|
||||
|
||||
def _local_context_data(self, queryset, name, value):
|
||||
@@ -453,19 +454,19 @@ class LocalConfigContextFilterSet(django_filters.FilterSet):
|
||||
class ObjectChangeFilterSet(BaseFilterSet):
|
||||
q = django_filters.CharFilter(
|
||||
method='search',
|
||||
label='Search',
|
||||
label=_('Search'),
|
||||
)
|
||||
time = django_filters.DateTimeFromToRangeFilter()
|
||||
changed_object_type = ContentTypeFilter()
|
||||
user_id = django_filters.ModelMultipleChoiceFilter(
|
||||
queryset=User.objects.all(),
|
||||
label='User (ID)',
|
||||
label=_('User (ID)'),
|
||||
)
|
||||
user = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='user__username',
|
||||
queryset=User.objects.all(),
|
||||
to_field_name='username',
|
||||
label='User name',
|
||||
label=_('User name'),
|
||||
)
|
||||
|
||||
class Meta:
|
||||
@@ -491,7 +492,7 @@ class ObjectChangeFilterSet(BaseFilterSet):
|
||||
class JobResultFilterSet(BaseFilterSet):
|
||||
q = django_filters.CharFilter(
|
||||
method='search',
|
||||
label='Search',
|
||||
label=_('Search'),
|
||||
)
|
||||
created = django_filters.DateTimeFilter()
|
||||
created__before = django_filters.DateTimeFilter(
|
||||
@@ -547,7 +548,7 @@ class JobResultFilterSet(BaseFilterSet):
|
||||
class ContentTypeFilterSet(django_filters.FilterSet):
|
||||
q = django_filters.CharFilter(
|
||||
method='search',
|
||||
label='Search',
|
||||
label=_('Search'),
|
||||
)
|
||||
|
||||
class Meta:
|
||||
|
@@ -1,4 +1,5 @@
|
||||
from django import forms
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
from extras.choices import *
|
||||
from extras.models import *
|
||||
@@ -37,7 +38,7 @@ class CustomFieldBulkEditForm(BulkEditForm):
|
||||
required=False
|
||||
)
|
||||
ui_visibility = forms.ChoiceField(
|
||||
label="UI visibility",
|
||||
label=_("UI visibility"),
|
||||
choices=add_blank_choice(CustomFieldVisibilityChoices),
|
||||
required=False,
|
||||
initial='',
|
||||
@@ -143,23 +144,23 @@ class WebhookBulkEditForm(BulkEditForm):
|
||||
http_method = forms.ChoiceField(
|
||||
choices=add_blank_choice(WebhookHttpMethodChoices),
|
||||
required=False,
|
||||
label='HTTP method'
|
||||
label=_('HTTP method')
|
||||
)
|
||||
payload_url = forms.CharField(
|
||||
required=False,
|
||||
label='Payload URL'
|
||||
label=_('Payload URL')
|
||||
)
|
||||
ssl_verification = forms.NullBooleanField(
|
||||
required=False,
|
||||
widget=BulkEditNullBooleanSelect(),
|
||||
label='SSL verification'
|
||||
label=_('SSL verification')
|
||||
)
|
||||
secret = forms.CharField(
|
||||
required=False
|
||||
)
|
||||
ca_file_path = forms.CharField(
|
||||
required=False,
|
||||
label='CA file path'
|
||||
label=_('CA file path')
|
||||
)
|
||||
|
||||
nullable_fields = ('secret', 'conditions', 'ca_file_path')
|
||||
|
@@ -2,6 +2,7 @@ from django import forms
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.contrib.postgres.forms import SimpleArrayField
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
from extras.choices import CustomFieldVisibilityChoices, CustomFieldTypeChoices
|
||||
from extras.models import *
|
||||
@@ -22,26 +23,26 @@ class CustomFieldCSVForm(CSVModelForm):
|
||||
content_types = CSVMultipleContentTypeField(
|
||||
queryset=ContentType.objects.all(),
|
||||
limit_choices_to=FeatureQuery('custom_fields'),
|
||||
help_text="One or more assigned object types"
|
||||
help_text=_("One or more assigned object types")
|
||||
)
|
||||
type = CSVChoiceField(
|
||||
choices=CustomFieldTypeChoices,
|
||||
help_text='Field data type (e.g. text, integer, etc.)'
|
||||
help_text=_('Field data type (e.g. text, integer, etc.)')
|
||||
)
|
||||
object_type = CSVContentTypeField(
|
||||
queryset=ContentType.objects.all(),
|
||||
limit_choices_to=FeatureQuery('custom_fields'),
|
||||
required=False,
|
||||
help_text="Object type (for object or multi-object fields)"
|
||||
help_text=_("Object type (for object or multi-object fields)")
|
||||
)
|
||||
choices = SimpleArrayField(
|
||||
base_field=forms.CharField(),
|
||||
required=False,
|
||||
help_text='Comma-separated list of field choices'
|
||||
help_text=_('Comma-separated list of field choices')
|
||||
)
|
||||
ui_visibility = CSVChoiceField(
|
||||
choices=CustomFieldVisibilityChoices,
|
||||
help_text='How the custom field is displayed in the user interface'
|
||||
help_text=_('How the custom field is displayed in the user interface')
|
||||
)
|
||||
|
||||
class Meta:
|
||||
@@ -57,7 +58,7 @@ class CustomLinkCSVForm(CSVModelForm):
|
||||
content_types = CSVMultipleContentTypeField(
|
||||
queryset=ContentType.objects.all(),
|
||||
limit_choices_to=FeatureQuery('custom_links'),
|
||||
help_text="One or more assigned object types"
|
||||
help_text=_("One or more assigned object types")
|
||||
)
|
||||
|
||||
class Meta:
|
||||
@@ -72,7 +73,7 @@ class ExportTemplateCSVForm(CSVModelForm):
|
||||
content_types = CSVMultipleContentTypeField(
|
||||
queryset=ContentType.objects.all(),
|
||||
limit_choices_to=FeatureQuery('export_templates'),
|
||||
help_text="One or more assigned object types"
|
||||
help_text=_("One or more assigned object types")
|
||||
)
|
||||
|
||||
class Meta:
|
||||
@@ -85,7 +86,7 @@ class ExportTemplateCSVForm(CSVModelForm):
|
||||
class SavedFilterCSVForm(CSVModelForm):
|
||||
content_types = CSVMultipleContentTypeField(
|
||||
queryset=ContentType.objects.all(),
|
||||
help_text="One or more assigned object types"
|
||||
help_text=_("One or more assigned object types")
|
||||
)
|
||||
|
||||
class Meta:
|
||||
@@ -99,7 +100,7 @@ class WebhookCSVForm(CSVModelForm):
|
||||
content_types = CSVMultipleContentTypeField(
|
||||
queryset=ContentType.objects.all(),
|
||||
limit_choices_to=FeatureQuery('webhooks'),
|
||||
help_text="One or more assigned object types"
|
||||
help_text=_("One or more assigned object types")
|
||||
)
|
||||
|
||||
class Meta:
|
||||
@@ -118,5 +119,5 @@ class TagCSVForm(CSVModelForm):
|
||||
model = Tag
|
||||
fields = ('name', 'slug', 'color', 'description')
|
||||
help_texts = {
|
||||
'color': mark_safe('RGB color in hexadecimal (e.g. <code>00ff00</code>)'),
|
||||
'color': mark_safe(_('RGB color in hexadecimal (e.g. <code>00ff00</code>)')),
|
||||
}
|
||||
|
@@ -41,7 +41,7 @@ class CustomFieldFilterForm(SavedFiltersMixin, FilterForm):
|
||||
queryset=ContentType.objects.all(),
|
||||
limit_choices_to=FeatureQuery('custom_fields'),
|
||||
required=False,
|
||||
label='Object type'
|
||||
label=_('Object type')
|
||||
)
|
||||
type = MultipleChoiceField(
|
||||
choices=CustomFieldTypeChoices,
|
||||
@@ -209,7 +209,7 @@ class WebhookFilterForm(SavedFiltersMixin, FilterForm):
|
||||
queryset=ContentType.objects.all(),
|
||||
limit_choices_to=FeatureQuery('webhooks'),
|
||||
required=False,
|
||||
label='Object type'
|
||||
label=_('Object type')
|
||||
)
|
||||
http_method = MultipleChoiceField(
|
||||
choices=WebhookHttpMethodChoices,
|
||||
|
@@ -1,5 +1,6 @@
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django import forms
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
from extras.models import *
|
||||
from extras.choices import CustomFieldVisibilityChoices
|
||||
@@ -66,7 +67,7 @@ class SavedFiltersMixin(forms.Form):
|
||||
filter = DynamicModelMultipleChoiceField(
|
||||
queryset=SavedFilter.objects.all(),
|
||||
required=False,
|
||||
label='Saved Filter',
|
||||
label=_('Saved Filter'),
|
||||
query_params={
|
||||
'usable': True,
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
from django import forms
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.http import QueryDict
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
from dcim.models import DeviceRole, DeviceType, Location, Platform, Region, Site, SiteGroup
|
||||
from extras.choices import *
|
||||
@@ -31,14 +32,14 @@ class CustomFieldForm(BootstrapMixin, forms.ModelForm):
|
||||
content_types = ContentTypeMultipleChoiceField(
|
||||
queryset=ContentType.objects.all(),
|
||||
limit_choices_to=FeatureQuery('custom_fields'),
|
||||
label='Model(s)'
|
||||
label=_('Model(s)')
|
||||
)
|
||||
object_type = ContentTypeChoiceField(
|
||||
queryset=ContentType.objects.all(),
|
||||
# TODO: Come up with a canonical way to register suitable models
|
||||
limit_choices_to=FeatureQuery('webhooks'),
|
||||
required=False,
|
||||
help_text="Type of the related object (for object/multi-object fields only)"
|
||||
help_text=_("Type of the related object (for object/multi-object fields only)")
|
||||
)
|
||||
|
||||
fieldsets = (
|
||||
@@ -54,8 +55,8 @@ class CustomFieldForm(BootstrapMixin, forms.ModelForm):
|
||||
model = CustomField
|
||||
fields = '__all__'
|
||||
help_texts = {
|
||||
'type': "The type of data stored in this field. For object/multi-object fields, select the related object "
|
||||
"type below."
|
||||
'type': _("The type of data stored in this field. For object/multi-object fields, select the related object "
|
||||
"type below.")
|
||||
}
|
||||
widgets = {
|
||||
'type': StaticSelect(),
|
||||
@@ -84,9 +85,9 @@ class CustomLinkForm(BootstrapMixin, forms.ModelForm):
|
||||
'link_url': forms.Textarea(attrs={'class': 'font-monospace'}),
|
||||
}
|
||||
help_texts = {
|
||||
'link_text': 'Jinja2 template code for the link text. Reference the object as <code>{{ object }}</code>. '
|
||||
'Links which render as empty text will not be displayed.',
|
||||
'link_url': 'Jinja2 template code for the link URL. Reference the object as <code>{{ object }}</code>.',
|
||||
'link_text': _('Jinja2 template code for the link text. Reference the object as <code>{{ object }}</code>. '
|
||||
'Links which render as empty text will not be displayed.'),
|
||||
'link_url': _('Jinja2 template code for the link URL. Reference the object as <code>{{ object }}</code>.'),
|
||||
}
|
||||
|
||||
|
||||
|
@@ -1,4 +1,5 @@
|
||||
from django import forms
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
from utilities.forms import BootstrapMixin, DateTimePicker
|
||||
|
||||
@@ -11,6 +12,6 @@ class ReportForm(BootstrapMixin, forms.Form):
|
||||
schedule_at = forms.DateTimeField(
|
||||
required=False,
|
||||
widget=DateTimePicker(),
|
||||
label="Schedule at",
|
||||
help_text="Schedule execution of report to a set time",
|
||||
label=_("Schedule at"),
|
||||
help_text=_("Schedule execution of report to a set time"),
|
||||
)
|
||||
|
@@ -1,4 +1,5 @@
|
||||
from django import forms
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
from utilities.forms import BootstrapMixin, DateTimePicker
|
||||
|
||||
@@ -11,14 +12,14 @@ class ScriptForm(BootstrapMixin, forms.Form):
|
||||
_commit = forms.BooleanField(
|
||||
required=False,
|
||||
initial=True,
|
||||
label="Commit changes",
|
||||
help_text="Commit changes to the database (uncheck for a dry-run)"
|
||||
label=_("Commit changes"),
|
||||
help_text=_("Commit changes to the database (uncheck for a dry-run)")
|
||||
)
|
||||
_schedule_at = forms.DateTimeField(
|
||||
required=False,
|
||||
widget=DateTimePicker(),
|
||||
label="Schedule at",
|
||||
help_text="Schedule execution of script to a set time",
|
||||
label=_("Schedule at"),
|
||||
help_text=_("Schedule execution of script to a set time"),
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
@@ -11,6 +11,7 @@ from django.db import models
|
||||
from django.urls import reverse
|
||||
from django.utils.html import escape
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
from extras.choices import *
|
||||
from extras.utils import FeatureQuery
|
||||
@@ -57,25 +58,25 @@ class CustomField(CloningMixin, ExportTemplatesMixin, WebhooksMixin, ChangeLogge
|
||||
to=ContentType,
|
||||
related_name='custom_fields',
|
||||
limit_choices_to=FeatureQuery('custom_fields'),
|
||||
help_text='The object(s) to which this field applies.'
|
||||
help_text=_('The object(s) to which this field applies.')
|
||||
)
|
||||
type = models.CharField(
|
||||
max_length=50,
|
||||
choices=CustomFieldTypeChoices,
|
||||
default=CustomFieldTypeChoices.TYPE_TEXT,
|
||||
help_text='The type of data this custom field holds'
|
||||
help_text=_('The type of data this custom field holds')
|
||||
)
|
||||
object_type = models.ForeignKey(
|
||||
to=ContentType,
|
||||
on_delete=models.PROTECT,
|
||||
blank=True,
|
||||
null=True,
|
||||
help_text='The type of NetBox object this field maps to (for object fields)'
|
||||
help_text=_('The type of NetBox object this field maps to (for object fields)')
|
||||
)
|
||||
name = models.CharField(
|
||||
max_length=50,
|
||||
unique=True,
|
||||
help_text='Internal field name',
|
||||
help_text=_('Internal field name'),
|
||||
validators=(
|
||||
RegexValidator(
|
||||
regex=r'^[a-z0-9_]+$',
|
||||
@@ -87,13 +88,13 @@ class CustomField(CloningMixin, ExportTemplatesMixin, WebhooksMixin, ChangeLogge
|
||||
label = models.CharField(
|
||||
max_length=50,
|
||||
blank=True,
|
||||
help_text='Name of the field as displayed to users (if not provided, '
|
||||
'the field\'s name will be used)'
|
||||
help_text=_('Name of the field as displayed to users (if not provided, '
|
||||
'the field\'s name will be used)')
|
||||
)
|
||||
group_name = models.CharField(
|
||||
max_length=50,
|
||||
blank=True,
|
||||
help_text="Custom fields within the same group will be displayed together"
|
||||
help_text=_("Custom fields within the same group will be displayed together")
|
||||
)
|
||||
description = models.CharField(
|
||||
max_length=200,
|
||||
@@ -101,64 +102,64 @@ class CustomField(CloningMixin, ExportTemplatesMixin, WebhooksMixin, ChangeLogge
|
||||
)
|
||||
required = models.BooleanField(
|
||||
default=False,
|
||||
help_text='If true, this field is required when creating new objects '
|
||||
'or editing an existing object.'
|
||||
help_text=_('If true, this field is required when creating new objects '
|
||||
'or editing an existing object.')
|
||||
)
|
||||
search_weight = models.PositiveSmallIntegerField(
|
||||
default=1000,
|
||||
help_text='Weighting for search. Lower values are considered more important. '
|
||||
'Fields with a search weight of zero will be ignored.'
|
||||
help_text=_('Weighting for search. Lower values are considered more important. '
|
||||
'Fields with a search weight of zero will be ignored.')
|
||||
)
|
||||
filter_logic = models.CharField(
|
||||
max_length=50,
|
||||
choices=CustomFieldFilterLogicChoices,
|
||||
default=CustomFieldFilterLogicChoices.FILTER_LOOSE,
|
||||
help_text='Loose matches any instance of a given string; exact '
|
||||
'matches the entire field.'
|
||||
help_text=_('Loose matches any instance of a given string; exact '
|
||||
'matches the entire field.')
|
||||
)
|
||||
default = models.JSONField(
|
||||
blank=True,
|
||||
null=True,
|
||||
help_text='Default value for the field (must be a JSON value). Encapsulate '
|
||||
'strings with double quotes (e.g. "Foo").'
|
||||
help_text=_('Default value for the field (must be a JSON value). Encapsulate '
|
||||
'strings with double quotes (e.g. "Foo").')
|
||||
)
|
||||
weight = models.PositiveSmallIntegerField(
|
||||
default=100,
|
||||
verbose_name='Display weight',
|
||||
help_text='Fields with higher weights appear lower in a form.'
|
||||
help_text=_('Fields with higher weights appear lower in a form.')
|
||||
)
|
||||
validation_minimum = models.IntegerField(
|
||||
blank=True,
|
||||
null=True,
|
||||
verbose_name='Minimum value',
|
||||
help_text='Minimum allowed value (for numeric fields)'
|
||||
help_text=_('Minimum allowed value (for numeric fields)')
|
||||
)
|
||||
validation_maximum = models.IntegerField(
|
||||
blank=True,
|
||||
null=True,
|
||||
verbose_name='Maximum value',
|
||||
help_text='Maximum allowed value (for numeric fields)'
|
||||
help_text=_('Maximum allowed value (for numeric fields)')
|
||||
)
|
||||
validation_regex = models.CharField(
|
||||
blank=True,
|
||||
validators=[validate_regex],
|
||||
max_length=500,
|
||||
verbose_name='Validation regex',
|
||||
help_text='Regular expression to enforce on text field values. Use ^ and $ to force matching of entire string. '
|
||||
'For example, <code>^[A-Z]{3}$</code> will limit values to exactly three uppercase letters.'
|
||||
help_text=_('Regular expression to enforce on text field values. Use ^ and $ to force matching of entire string. '
|
||||
'For example, <code>^[A-Z]{3}$</code> will limit values to exactly three uppercase letters.')
|
||||
)
|
||||
choices = ArrayField(
|
||||
base_field=models.CharField(max_length=100),
|
||||
blank=True,
|
||||
null=True,
|
||||
help_text='Comma-separated list of available choices (for selection fields)'
|
||||
help_text=_('Comma-separated list of available choices (for selection fields)')
|
||||
)
|
||||
ui_visibility = models.CharField(
|
||||
max_length=50,
|
||||
choices=CustomFieldVisibilityChoices,
|
||||
default=CustomFieldVisibilityChoices.VISIBILITY_READ_WRITE,
|
||||
verbose_name='UI visibility',
|
||||
help_text='Specifies the visibility of custom field in the UI'
|
||||
help_text=_('Specifies the visibility of custom field in the UI')
|
||||
)
|
||||
|
||||
objects = CustomFieldManager()
|
||||
|
@@ -12,6 +12,7 @@ from django.http import HttpResponse, QueryDict
|
||||
from django.urls import reverse
|
||||
from django.utils import timezone
|
||||
from django.utils.formats import date_format
|
||||
from django.utils.translation import gettext as _
|
||||
from rest_framework.utils.encoders import JSONEncoder
|
||||
import django_rq
|
||||
|
||||
@@ -51,7 +52,7 @@ class Webhook(ExportTemplatesMixin, WebhooksMixin, ChangeLoggedModel):
|
||||
related_name='webhooks',
|
||||
verbose_name='Object types',
|
||||
limit_choices_to=FeatureQuery('webhooks'),
|
||||
help_text="The object(s) to which this Webhook applies."
|
||||
help_text=_("The object(s) to which this Webhook applies.")
|
||||
)
|
||||
name = models.CharField(
|
||||
max_length=150,
|
||||
@@ -59,21 +60,21 @@ class Webhook(ExportTemplatesMixin, WebhooksMixin, ChangeLoggedModel):
|
||||
)
|
||||
type_create = models.BooleanField(
|
||||
default=False,
|
||||
help_text="Call this webhook when a matching object is created."
|
||||
help_text=_("Call this webhook when a matching object is created.")
|
||||
)
|
||||
type_update = models.BooleanField(
|
||||
default=False,
|
||||
help_text="Call this webhook when a matching object is updated."
|
||||
help_text=_("Call this webhook when a matching object is updated.")
|
||||
)
|
||||
type_delete = models.BooleanField(
|
||||
default=False,
|
||||
help_text="Call this webhook when a matching object is deleted."
|
||||
help_text=_("Call this webhook when a matching object is deleted.")
|
||||
)
|
||||
payload_url = models.CharField(
|
||||
max_length=500,
|
||||
verbose_name='URL',
|
||||
help_text='This URL will be called using the HTTP method defined when the webhook is called. '
|
||||
'Jinja2 template processing is supported with the same context as the request body.'
|
||||
help_text=_('This URL will be called using the HTTP method defined when the webhook is called. '
|
||||
'Jinja2 template processing is supported with the same context as the request body.')
|
||||
)
|
||||
enabled = models.BooleanField(
|
||||
default=True
|
||||
@@ -88,46 +89,46 @@ class Webhook(ExportTemplatesMixin, WebhooksMixin, ChangeLoggedModel):
|
||||
max_length=100,
|
||||
default=HTTP_CONTENT_TYPE_JSON,
|
||||
verbose_name='HTTP content type',
|
||||
help_text='The complete list of official content types is available '
|
||||
'<a href="https://www.iana.org/assignments/media-types/media-types.xhtml">here</a>.'
|
||||
help_text=_('The complete list of official content types is available '
|
||||
'<a href="https://www.iana.org/assignments/media-types/media-types.xhtml">here</a>.')
|
||||
)
|
||||
additional_headers = models.TextField(
|
||||
blank=True,
|
||||
help_text="User-supplied HTTP headers to be sent with the request in addition to the HTTP content type. "
|
||||
"Headers should be defined in the format <code>Name: Value</code>. Jinja2 template processing is "
|
||||
"supported with the same context as the request body (below)."
|
||||
help_text=_("User-supplied HTTP headers to be sent with the request in addition to the HTTP content type. "
|
||||
"Headers should be defined in the format <code>Name: Value</code>. Jinja2 template processing is "
|
||||
"supported with the same context as the request body (below).")
|
||||
)
|
||||
body_template = models.TextField(
|
||||
blank=True,
|
||||
help_text='Jinja2 template for a custom request body. If blank, a JSON object representing the change will be '
|
||||
'included. Available context data includes: <code>event</code>, <code>model</code>, '
|
||||
'<code>timestamp</code>, <code>username</code>, <code>request_id</code>, and <code>data</code>.'
|
||||
help_text=_('Jinja2 template for a custom request body. If blank, a JSON object representing the change will be '
|
||||
'included. Available context data includes: <code>event</code>, <code>model</code>, '
|
||||
'<code>timestamp</code>, <code>username</code>, <code>request_id</code>, and <code>data</code>.')
|
||||
)
|
||||
secret = models.CharField(
|
||||
max_length=255,
|
||||
blank=True,
|
||||
help_text="When provided, the request will include a 'X-Hook-Signature' "
|
||||
"header containing a HMAC hex digest of the payload body using "
|
||||
"the secret as the key. The secret is not transmitted in "
|
||||
"the request."
|
||||
help_text=_("When provided, the request will include a 'X-Hook-Signature' "
|
||||
"header containing a HMAC hex digest of the payload body using "
|
||||
"the secret as the key. The secret is not transmitted in "
|
||||
"the request.")
|
||||
)
|
||||
conditions = models.JSONField(
|
||||
blank=True,
|
||||
null=True,
|
||||
help_text="A set of conditions which determine whether the webhook will be generated."
|
||||
help_text=_("A set of conditions which determine whether the webhook will be generated.")
|
||||
)
|
||||
ssl_verification = models.BooleanField(
|
||||
default=True,
|
||||
verbose_name='SSL verification',
|
||||
help_text="Enable SSL certificate verification. Disable with caution!"
|
||||
help_text=_("Enable SSL certificate verification. Disable with caution!")
|
||||
)
|
||||
ca_file_path = models.CharField(
|
||||
max_length=4096,
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name='CA File Path',
|
||||
help_text='The specific CA certificate file to use for SSL verification. '
|
||||
'Leave blank to use the system defaults.'
|
||||
help_text=_('The specific CA certificate file to use for SSL verification. '
|
||||
'Leave blank to use the system defaults.')
|
||||
)
|
||||
|
||||
class Meta:
|
||||
@@ -201,7 +202,7 @@ class CustomLink(CloningMixin, ExportTemplatesMixin, WebhooksMixin, ChangeLogged
|
||||
content_types = models.ManyToManyField(
|
||||
to=ContentType,
|
||||
related_name='custom_links',
|
||||
help_text='The object type(s) to which this link applies.'
|
||||
help_text=_('The object type(s) to which this link applies.')
|
||||
)
|
||||
name = models.CharField(
|
||||
max_length=100,
|
||||
@@ -211,11 +212,11 @@ class CustomLink(CloningMixin, ExportTemplatesMixin, WebhooksMixin, ChangeLogged
|
||||
default=True
|
||||
)
|
||||
link_text = models.TextField(
|
||||
help_text="Jinja2 template code for link text"
|
||||
help_text=_("Jinja2 template code for link text")
|
||||
)
|
||||
link_url = models.TextField(
|
||||
verbose_name='Link URL',
|
||||
help_text="Jinja2 template code for link URL"
|
||||
help_text=_("Jinja2 template code for link URL")
|
||||
)
|
||||
weight = models.PositiveSmallIntegerField(
|
||||
default=100
|
||||
@@ -223,17 +224,17 @@ class CustomLink(CloningMixin, ExportTemplatesMixin, WebhooksMixin, ChangeLogged
|
||||
group_name = models.CharField(
|
||||
max_length=50,
|
||||
blank=True,
|
||||
help_text="Links with the same group will appear as a dropdown menu"
|
||||
help_text=_("Links with the same group will appear as a dropdown menu")
|
||||
)
|
||||
button_class = models.CharField(
|
||||
max_length=30,
|
||||
choices=CustomLinkButtonClassChoices,
|
||||
default=CustomLinkButtonClassChoices.DEFAULT,
|
||||
help_text="The class of the first link in a group will be used for the dropdown button"
|
||||
help_text=_("The class of the first link in a group will be used for the dropdown button")
|
||||
)
|
||||
new_window = models.BooleanField(
|
||||
default=False,
|
||||
help_text="Force link to open in a new window"
|
||||
help_text=_("Force link to open in a new window")
|
||||
)
|
||||
|
||||
clone_fields = (
|
||||
@@ -272,7 +273,7 @@ class ExportTemplate(ExportTemplatesMixin, WebhooksMixin, ChangeLoggedModel):
|
||||
content_types = models.ManyToManyField(
|
||||
to=ContentType,
|
||||
related_name='export_templates',
|
||||
help_text='The object type(s) to which this template applies.'
|
||||
help_text=_('The object type(s) to which this template applies.')
|
||||
)
|
||||
name = models.CharField(
|
||||
max_length=100
|
||||
@@ -282,23 +283,23 @@ class ExportTemplate(ExportTemplatesMixin, WebhooksMixin, ChangeLoggedModel):
|
||||
blank=True
|
||||
)
|
||||
template_code = models.TextField(
|
||||
help_text='Jinja2 template code. The list of objects being exported is passed as a context variable named '
|
||||
'<code>queryset</code>.'
|
||||
help_text=_('Jinja2 template code. The list of objects being exported is passed as a context variable named '
|
||||
'<code>queryset</code>.')
|
||||
)
|
||||
mime_type = models.CharField(
|
||||
max_length=50,
|
||||
blank=True,
|
||||
verbose_name='MIME type',
|
||||
help_text='Defaults to <code>text/plain</code>'
|
||||
help_text=_('Defaults to <code>text/plain</code>')
|
||||
)
|
||||
file_extension = models.CharField(
|
||||
max_length=15,
|
||||
blank=True,
|
||||
help_text='Extension to append to the rendered filename'
|
||||
help_text=_('Extension to append to the rendered filename')
|
||||
)
|
||||
as_attachment = models.BooleanField(
|
||||
default=True,
|
||||
help_text="Download file as attachment"
|
||||
help_text=_("Download file as attachment")
|
||||
)
|
||||
|
||||
class Meta:
|
||||
@@ -358,7 +359,7 @@ class SavedFilter(CloningMixin, ExportTemplatesMixin, WebhooksMixin, ChangeLogge
|
||||
content_types = models.ManyToManyField(
|
||||
to=ContentType,
|
||||
related_name='saved_filters',
|
||||
help_text='The object type(s) to which this filter applies.'
|
||||
help_text=_('The object type(s) to which this filter applies.')
|
||||
)
|
||||
name = models.CharField(
|
||||
max_length=100,
|
||||
@@ -553,7 +554,7 @@ class JobResult(models.Model):
|
||||
related_name='job_results',
|
||||
verbose_name='Object types',
|
||||
limit_choices_to=FeatureQuery('job_results'),
|
||||
help_text="The object type to which this job result applies",
|
||||
help_text=_("The object type to which this job result applies"),
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
created = models.DateTimeField(
|
||||
|
@@ -1,3 +1,4 @@
|
||||
from django.utils.translation import gettext as _
|
||||
from extras.plugins import PluginMenu, PluginMenuButton, PluginMenuItem
|
||||
|
||||
|
||||
@@ -25,7 +26,7 @@ items = (
|
||||
)
|
||||
|
||||
menu = PluginMenu(
|
||||
label='Dummy',
|
||||
label=_('Dummy'),
|
||||
groups=(('Group 1', items),),
|
||||
)
|
||||
menu_items = items
|
||||
|
Reference in New Issue
Block a user