mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-16 04:02:52 -06:00
Merge v3.1.3
This commit is contained in:
commit
3bb485d0b8
2
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
2
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
@ -14,7 +14,7 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: NetBox version
|
label: NetBox version
|
||||||
description: What version of NetBox are you currently running?
|
description: What version of NetBox are you currently running?
|
||||||
placeholder: v3.1.2
|
placeholder: v3.1.3
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: dropdown
|
- type: dropdown
|
||||||
|
2
.github/ISSUE_TEMPLATE/feature_request.yaml
vendored
2
.github/ISSUE_TEMPLATE/feature_request.yaml
vendored
@ -14,7 +14,7 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: NetBox version
|
label: NetBox version
|
||||||
description: What version of NetBox are you currently running?
|
description: What version of NetBox are you currently running?
|
||||||
placeholder: v3.1.2
|
placeholder: v3.1.3
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: dropdown
|
- type: dropdown
|
||||||
|
@ -1,16 +1,23 @@
|
|||||||
# NetBox v3.1
|
# NetBox v3.1
|
||||||
|
|
||||||
## v3.1.3 (FUTURE)
|
## v3.1.4 (FUTURE)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## v3.1.3 (2021-12-29)
|
||||||
|
|
||||||
### Enhancements
|
### Enhancements
|
||||||
|
|
||||||
* [#6782](https://github.com/netbox-community/netbox/issues/6782) - Enable the inclusion of custom links in tables
|
* [#6782](https://github.com/netbox-community/netbox/issues/6782) - Enable the inclusion of custom links in tables
|
||||||
|
* [#7600](https://github.com/netbox-community/netbox/issues/7600) - Include count of available IPs on prefix view
|
||||||
|
* [#8034](https://github.com/netbox-community/netbox/issues/8034) - Enable specifying custom field validators during CSV import
|
||||||
* [#8100](https://github.com/netbox-community/netbox/issues/8100) - Add "other" choice for FHRP group protocol
|
* [#8100](https://github.com/netbox-community/netbox/issues/8100) - Add "other" choice for FHRP group protocol
|
||||||
* [#8175](https://github.com/netbox-community/netbox/issues/8175) - Display parent object when attaching an image
|
* [#8175](https://github.com/netbox-community/netbox/issues/8175) - Display parent object when attaching an image
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
* [#7246](https://github.com/netbox-community/netbox/issues/7246) - Don't attempt to URL-decode NAPALM response payloads
|
* [#7246](https://github.com/netbox-community/netbox/issues/7246) - Don't attempt to URL-decode NAPALM response payloads
|
||||||
|
* [#7290](https://github.com/netbox-community/netbox/issues/7290) - Defer loading API-backed form fields
|
||||||
* [#7887](https://github.com/netbox-community/netbox/issues/7887) - Forward `HTTP_X_FORWARDED_FOR` to custom scripts
|
* [#7887](https://github.com/netbox-community/netbox/issues/7887) - Forward `HTTP_X_FORWARDED_FOR` to custom scripts
|
||||||
* [#7962](https://github.com/netbox-community/netbox/issues/7962) - Fix user menu under report/script result view
|
* [#7962](https://github.com/netbox-community/netbox/issues/7962) - Fix user menu under report/script result view
|
||||||
* [#7972](https://github.com/netbox-community/netbox/issues/7972) - Standardize name of `RemoteUserBackend` logger
|
* [#7972](https://github.com/netbox-community/netbox/issues/7972) - Standardize name of `RemoteUserBackend` logger
|
||||||
|
@ -26,14 +26,12 @@ class ProviderFilterForm(CustomFieldModelFilterForm):
|
|||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Region'),
|
label=_('Region')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
site_group_id = DynamicModelMultipleChoiceField(
|
site_group_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=SiteGroup.objects.all(),
|
queryset=SiteGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Site group'),
|
label=_('Site group')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
site_id = DynamicModelMultipleChoiceField(
|
site_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
@ -42,8 +40,7 @@ class ProviderFilterForm(CustomFieldModelFilterForm):
|
|||||||
'region_id': '$region_id',
|
'region_id': '$region_id',
|
||||||
'site_group_id': '$site_group_id',
|
'site_group_id': '$site_group_id',
|
||||||
},
|
},
|
||||||
label=_('Site'),
|
label=_('Site')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
asn = forms.IntegerField(
|
asn = forms.IntegerField(
|
||||||
required=False,
|
required=False,
|
||||||
@ -61,8 +58,7 @@ class ProviderNetworkFilterForm(CustomFieldModelFilterForm):
|
|||||||
provider_id = DynamicModelMultipleChoiceField(
|
provider_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Provider.objects.all(),
|
queryset=Provider.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Provider'),
|
label=_('Provider')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
service_id = forms.CharField(
|
service_id = forms.CharField(
|
||||||
max_length=100,
|
max_length=100,
|
||||||
@ -88,14 +84,12 @@ class CircuitFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
type_id = DynamicModelMultipleChoiceField(
|
type_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=CircuitType.objects.all(),
|
queryset=CircuitType.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Type'),
|
label=_('Type')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
provider_id = DynamicModelMultipleChoiceField(
|
provider_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Provider.objects.all(),
|
queryset=Provider.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Provider'),
|
label=_('Provider')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
provider_network_id = DynamicModelMultipleChoiceField(
|
provider_network_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=ProviderNetwork.objects.all(),
|
queryset=ProviderNetwork.objects.all(),
|
||||||
@ -103,8 +97,7 @@ class CircuitFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
query_params={
|
query_params={
|
||||||
'provider_id': '$provider_id'
|
'provider_id': '$provider_id'
|
||||||
},
|
},
|
||||||
label=_('Provider network'),
|
label=_('Provider network')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
status = forms.MultipleChoiceField(
|
status = forms.MultipleChoiceField(
|
||||||
choices=CircuitStatusChoices,
|
choices=CircuitStatusChoices,
|
||||||
@ -114,14 +107,12 @@ class CircuitFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Region'),
|
label=_('Region')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
site_group_id = DynamicModelMultipleChoiceField(
|
site_group_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=SiteGroup.objects.all(),
|
queryset=SiteGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Site group'),
|
label=_('Site group')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
site_id = DynamicModelMultipleChoiceField(
|
site_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
@ -130,8 +121,7 @@ class CircuitFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
'region_id': '$region_id',
|
'region_id': '$region_id',
|
||||||
'site_group_id': '$site_group_id',
|
'site_group_id': '$site_group_id',
|
||||||
},
|
},
|
||||||
label=_('Site'),
|
label=_('Site')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
commit_rate = forms.IntegerField(
|
commit_rate = forms.IntegerField(
|
||||||
required=False,
|
required=False,
|
||||||
|
@ -62,14 +62,12 @@ class DeviceComponentFilterForm(CustomFieldModelFilterForm):
|
|||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Region'),
|
label=_('Region')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
site_group_id = DynamicModelMultipleChoiceField(
|
site_group_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=SiteGroup.objects.all(),
|
queryset=SiteGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Site group'),
|
label=_('Site group')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
site_id = DynamicModelMultipleChoiceField(
|
site_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
@ -78,8 +76,7 @@ class DeviceComponentFilterForm(CustomFieldModelFilterForm):
|
|||||||
'region_id': '$region_id',
|
'region_id': '$region_id',
|
||||||
'group_id': '$site_group_id',
|
'group_id': '$site_group_id',
|
||||||
},
|
},
|
||||||
label=_('Site'),
|
label=_('Site')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
location_id = DynamicModelMultipleChoiceField(
|
location_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Location.objects.all(),
|
queryset=Location.objects.all(),
|
||||||
@ -87,14 +84,12 @@ class DeviceComponentFilterForm(CustomFieldModelFilterForm):
|
|||||||
query_params={
|
query_params={
|
||||||
'site_id': '$site_id',
|
'site_id': '$site_id',
|
||||||
},
|
},
|
||||||
label=_('Location'),
|
label=_('Location')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
virtual_chassis_id = DynamicModelMultipleChoiceField(
|
virtual_chassis_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=VirtualChassis.objects.all(),
|
queryset=VirtualChassis.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Virtual Chassis'),
|
label=_('Virtual Chassis')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
device_id = DynamicModelMultipleChoiceField(
|
device_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Device.objects.all(),
|
queryset=Device.objects.all(),
|
||||||
@ -104,8 +99,7 @@ class DeviceComponentFilterForm(CustomFieldModelFilterForm):
|
|||||||
'location_id': '$location_id',
|
'location_id': '$location_id',
|
||||||
'virtual_chassis_id': '$virtual_chassis_id'
|
'virtual_chassis_id': '$virtual_chassis_id'
|
||||||
},
|
},
|
||||||
label=_('Device'),
|
label=_('Device')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -114,8 +108,7 @@ class RegionFilterForm(CustomFieldModelFilterForm):
|
|||||||
parent_id = DynamicModelMultipleChoiceField(
|
parent_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Parent region'),
|
label=_('Parent region')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
@ -125,8 +118,7 @@ class SiteGroupFilterForm(CustomFieldModelFilterForm):
|
|||||||
parent_id = DynamicModelMultipleChoiceField(
|
parent_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=SiteGroup.objects.all(),
|
queryset=SiteGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Parent group'),
|
label=_('Parent group')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
@ -147,20 +139,17 @@ class SiteFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Region'),
|
label=_('Region')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
group_id = DynamicModelMultipleChoiceField(
|
group_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=SiteGroup.objects.all(),
|
queryset=SiteGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Site group'),
|
label=_('Site group')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
asn_id = DynamicModelMultipleChoiceField(
|
asn_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=ASN.objects.all(),
|
queryset=ASN.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('ASNs'),
|
label=_('ASNs')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
@ -175,14 +164,12 @@ class LocationFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Region'),
|
label=_('Region')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
site_group_id = DynamicModelMultipleChoiceField(
|
site_group_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=SiteGroup.objects.all(),
|
queryset=SiteGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Site group'),
|
label=_('Site group')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
site_id = DynamicModelMultipleChoiceField(
|
site_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
@ -191,8 +178,7 @@ class LocationFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
'region_id': '$region_id',
|
'region_id': '$region_id',
|
||||||
'group_id': '$site_group_id',
|
'group_id': '$site_group_id',
|
||||||
},
|
},
|
||||||
label=_('Site'),
|
label=_('Site')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
parent_id = DynamicModelMultipleChoiceField(
|
parent_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Location.objects.all(),
|
queryset=Location.objects.all(),
|
||||||
@ -201,8 +187,7 @@ class LocationFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
'region_id': '$region_id',
|
'region_id': '$region_id',
|
||||||
'site_id': '$site_id',
|
'site_id': '$site_id',
|
||||||
},
|
},
|
||||||
label=_('Parent'),
|
label=_('Parent')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
@ -224,8 +209,7 @@ class RackFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Region'),
|
label=_('Region')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
site_id = DynamicModelMultipleChoiceField(
|
site_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
@ -233,8 +217,7 @@ class RackFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
query_params={
|
query_params={
|
||||||
'region_id': '$region_id'
|
'region_id': '$region_id'
|
||||||
},
|
},
|
||||||
label=_('Site'),
|
label=_('Site')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
location_id = DynamicModelMultipleChoiceField(
|
location_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Location.objects.all(),
|
queryset=Location.objects.all(),
|
||||||
@ -243,8 +226,7 @@ class RackFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
query_params={
|
query_params={
|
||||||
'site_id': '$site_id'
|
'site_id': '$site_id'
|
||||||
},
|
},
|
||||||
label=_('Location'),
|
label=_('Location')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
status = forms.MultipleChoiceField(
|
status = forms.MultipleChoiceField(
|
||||||
choices=RackStatusChoices,
|
choices=RackStatusChoices,
|
||||||
@ -265,8 +247,7 @@ class RackFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
queryset=RackRole.objects.all(),
|
queryset=RackRole.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
null_option='None',
|
null_option='None',
|
||||||
label=_('Role'),
|
label=_('Role')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
serial = forms.CharField(
|
serial = forms.CharField(
|
||||||
required=False
|
required=False
|
||||||
@ -285,8 +266,7 @@ class RackElevationFilterForm(RackFilterForm):
|
|||||||
query_params={
|
query_params={
|
||||||
'site_id': '$site_id',
|
'site_id': '$site_id',
|
||||||
'location_id': '$location_id',
|
'location_id': '$location_id',
|
||||||
},
|
}
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -301,8 +281,7 @@ class RackReservationFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Region'),
|
label=_('Region')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
site_id = DynamicModelMultipleChoiceField(
|
site_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
@ -310,15 +289,13 @@ class RackReservationFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
query_params={
|
query_params={
|
||||||
'region_id': '$region_id'
|
'region_id': '$region_id'
|
||||||
},
|
},
|
||||||
label=_('Site'),
|
label=_('Site')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
location_id = DynamicModelMultipleChoiceField(
|
location_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Location.objects.prefetch_related('site'),
|
queryset=Location.objects.prefetch_related('site'),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Location'),
|
label=_('Location'),
|
||||||
null_option='None',
|
null_option='None'
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
user_id = DynamicModelMultipleChoiceField(
|
user_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=User.objects.all(),
|
queryset=User.objects.all(),
|
||||||
@ -326,8 +303,7 @@ class RackReservationFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
label=_('User'),
|
label=_('User'),
|
||||||
widget=APISelectMultiple(
|
widget=APISelectMultiple(
|
||||||
api_url='/api/users/users/',
|
api_url='/api/users/users/',
|
||||||
),
|
)
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
@ -347,8 +323,7 @@ class DeviceTypeFilterForm(CustomFieldModelFilterForm):
|
|||||||
manufacturer_id = DynamicModelMultipleChoiceField(
|
manufacturer_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Manufacturer.objects.all(),
|
queryset=Manufacturer.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Manufacturer'),
|
label=_('Manufacturer')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
part_number = forms.CharField(
|
part_number = forms.CharField(
|
||||||
required=False
|
required=False
|
||||||
@ -479,8 +454,7 @@ class PlatformFilterForm(CustomFieldModelFilterForm):
|
|||||||
manufacturer_id = DynamicModelMultipleChoiceField(
|
manufacturer_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Manufacturer.objects.all(),
|
queryset=Manufacturer.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Manufacturer'),
|
label=_('Manufacturer')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
@ -501,14 +475,12 @@ class DeviceFilterForm(LocalConfigContextFilterForm, TenancyFilterForm, CustomFi
|
|||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Region'),
|
label=_('Region')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
site_group_id = DynamicModelMultipleChoiceField(
|
site_group_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=SiteGroup.objects.all(),
|
queryset=SiteGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Site group'),
|
label=_('Site group')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
site_id = DynamicModelMultipleChoiceField(
|
site_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
@ -517,8 +489,7 @@ class DeviceFilterForm(LocalConfigContextFilterForm, TenancyFilterForm, CustomFi
|
|||||||
'region_id': '$region_id',
|
'region_id': '$region_id',
|
||||||
'group_id': '$site_group_id',
|
'group_id': '$site_group_id',
|
||||||
},
|
},
|
||||||
label=_('Site'),
|
label=_('Site')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
location_id = DynamicModelMultipleChoiceField(
|
location_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Location.objects.all(),
|
queryset=Location.objects.all(),
|
||||||
@ -527,8 +498,7 @@ class DeviceFilterForm(LocalConfigContextFilterForm, TenancyFilterForm, CustomFi
|
|||||||
query_params={
|
query_params={
|
||||||
'site_id': '$site_id'
|
'site_id': '$site_id'
|
||||||
},
|
},
|
||||||
label=_('Location'),
|
label=_('Location')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
rack_id = DynamicModelMultipleChoiceField(
|
rack_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Rack.objects.all(),
|
queryset=Rack.objects.all(),
|
||||||
@ -538,20 +508,17 @@ class DeviceFilterForm(LocalConfigContextFilterForm, TenancyFilterForm, CustomFi
|
|||||||
'site_id': '$site_id',
|
'site_id': '$site_id',
|
||||||
'location_id': '$location_id',
|
'location_id': '$location_id',
|
||||||
},
|
},
|
||||||
label=_('Rack'),
|
label=_('Rack')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
role_id = DynamicModelMultipleChoiceField(
|
role_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=DeviceRole.objects.all(),
|
queryset=DeviceRole.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Role'),
|
label=_('Role')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
manufacturer_id = DynamicModelMultipleChoiceField(
|
manufacturer_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Manufacturer.objects.all(),
|
queryset=Manufacturer.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Manufacturer'),
|
label=_('Manufacturer')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
device_type_id = DynamicModelMultipleChoiceField(
|
device_type_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=DeviceType.objects.all(),
|
queryset=DeviceType.objects.all(),
|
||||||
@ -559,15 +526,13 @@ class DeviceFilterForm(LocalConfigContextFilterForm, TenancyFilterForm, CustomFi
|
|||||||
query_params={
|
query_params={
|
||||||
'manufacturer_id': '$manufacturer_id'
|
'manufacturer_id': '$manufacturer_id'
|
||||||
},
|
},
|
||||||
label=_('Model'),
|
label=_('Model')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
platform_id = DynamicModelMultipleChoiceField(
|
platform_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Platform.objects.all(),
|
queryset=Platform.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
null_option='None',
|
null_option='None',
|
||||||
label=_('Platform'),
|
label=_('Platform')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
status = forms.MultipleChoiceField(
|
status = forms.MultipleChoiceField(
|
||||||
choices=DeviceStatusChoices,
|
choices=DeviceStatusChoices,
|
||||||
@ -689,14 +654,12 @@ class VirtualChassisFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Region'),
|
label=_('Region')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
site_group_id = DynamicModelMultipleChoiceField(
|
site_group_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=SiteGroup.objects.all(),
|
queryset=SiteGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Site group'),
|
label=_('Site group')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
site_id = DynamicModelMultipleChoiceField(
|
site_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
@ -705,8 +668,7 @@ class VirtualChassisFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
'region_id': '$region_id',
|
'region_id': '$region_id',
|
||||||
'group_id': '$site_group_id',
|
'group_id': '$site_group_id',
|
||||||
},
|
},
|
||||||
label=_('Site'),
|
label=_('Site')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
@ -722,8 +684,7 @@ class CableFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Region'),
|
label=_('Region')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
site_id = DynamicModelMultipleChoiceField(
|
site_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
@ -731,8 +692,7 @@ class CableFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
query_params={
|
query_params={
|
||||||
'region_id': '$region_id'
|
'region_id': '$region_id'
|
||||||
},
|
},
|
||||||
label=_('Site'),
|
label=_('Site')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
rack_id = DynamicModelMultipleChoiceField(
|
rack_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Rack.objects.all(),
|
queryset=Rack.objects.all(),
|
||||||
@ -741,8 +701,7 @@ class CableFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
null_option='None',
|
null_option='None',
|
||||||
query_params={
|
query_params={
|
||||||
'site_id': '$site_id'
|
'site_id': '$site_id'
|
||||||
},
|
}
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
type = forms.MultipleChoiceField(
|
type = forms.MultipleChoiceField(
|
||||||
choices=add_blank_choice(CableTypeChoices),
|
choices=add_blank_choice(CableTypeChoices),
|
||||||
@ -765,8 +724,7 @@ class CableFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
'tenant_id': '$tenant_id',
|
'tenant_id': '$tenant_id',
|
||||||
'rack_id': '$rack_id',
|
'rack_id': '$rack_id',
|
||||||
},
|
},
|
||||||
label=_('Device'),
|
label=_('Device')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
@ -780,14 +738,12 @@ class PowerPanelFilterForm(CustomFieldModelFilterForm):
|
|||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Region'),
|
label=_('Region')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
site_group_id = DynamicModelMultipleChoiceField(
|
site_group_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=SiteGroup.objects.all(),
|
queryset=SiteGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Site group'),
|
label=_('Site group')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
site_id = DynamicModelMultipleChoiceField(
|
site_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
@ -796,8 +752,7 @@ class PowerPanelFilterForm(CustomFieldModelFilterForm):
|
|||||||
'region_id': '$region_id',
|
'region_id': '$region_id',
|
||||||
'group_id': '$site_group_id',
|
'group_id': '$site_group_id',
|
||||||
},
|
},
|
||||||
label=_('Site'),
|
label=_('Site')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
location_id = DynamicModelMultipleChoiceField(
|
location_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Location.objects.all(),
|
queryset=Location.objects.all(),
|
||||||
@ -806,8 +761,7 @@ class PowerPanelFilterForm(CustomFieldModelFilterForm):
|
|||||||
query_params={
|
query_params={
|
||||||
'site_id': '$site_id'
|
'site_id': '$site_id'
|
||||||
},
|
},
|
||||||
label=_('Location'),
|
label=_('Location')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
@ -823,14 +777,12 @@ class PowerFeedFilterForm(CustomFieldModelFilterForm):
|
|||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Region'),
|
label=_('Region')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
site_group_id = DynamicModelMultipleChoiceField(
|
site_group_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=SiteGroup.objects.all(),
|
queryset=SiteGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Site group'),
|
label=_('Site group')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
site_id = DynamicModelMultipleChoiceField(
|
site_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
@ -838,8 +790,7 @@ class PowerFeedFilterForm(CustomFieldModelFilterForm):
|
|||||||
query_params={
|
query_params={
|
||||||
'region_id': '$region_id'
|
'region_id': '$region_id'
|
||||||
},
|
},
|
||||||
label=_('Site'),
|
label=_('Site')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
power_panel_id = DynamicModelMultipleChoiceField(
|
power_panel_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=PowerPanel.objects.all(),
|
queryset=PowerPanel.objects.all(),
|
||||||
@ -848,8 +799,7 @@ class PowerFeedFilterForm(CustomFieldModelFilterForm):
|
|||||||
query_params={
|
query_params={
|
||||||
'site_id': '$site_id'
|
'site_id': '$site_id'
|
||||||
},
|
},
|
||||||
label=_('Power panel'),
|
label=_('Power panel')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
rack_id = DynamicModelMultipleChoiceField(
|
rack_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Rack.objects.all(),
|
queryset=Rack.objects.all(),
|
||||||
@ -858,8 +808,7 @@ class PowerFeedFilterForm(CustomFieldModelFilterForm):
|
|||||||
query_params={
|
query_params={
|
||||||
'site_id': '$site_id'
|
'site_id': '$site_id'
|
||||||
},
|
},
|
||||||
label=_('Rack'),
|
label=_('Rack')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
status = forms.MultipleChoiceField(
|
status = forms.MultipleChoiceField(
|
||||||
choices=PowerFeedStatusChoices,
|
choices=PowerFeedStatusChoices,
|
||||||
@ -1109,8 +1058,7 @@ class InventoryItemFilterForm(DeviceComponentFilterForm):
|
|||||||
manufacturer_id = DynamicModelMultipleChoiceField(
|
manufacturer_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Manufacturer.objects.all(),
|
queryset=Manufacturer.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Manufacturer'),
|
label=_('Manufacturer')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
serial = forms.CharField(
|
serial = forms.CharField(
|
||||||
required=False
|
required=False
|
||||||
@ -1144,8 +1092,7 @@ class ConsoleConnectionFilterForm(FilterForm):
|
|||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Region'),
|
label=_('Region')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
site_id = DynamicModelMultipleChoiceField(
|
site_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
@ -1153,8 +1100,7 @@ class ConsoleConnectionFilterForm(FilterForm):
|
|||||||
query_params={
|
query_params={
|
||||||
'region_id': '$region_id'
|
'region_id': '$region_id'
|
||||||
},
|
},
|
||||||
label=_('Site'),
|
label=_('Site')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
device_id = DynamicModelMultipleChoiceField(
|
device_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Device.objects.all(),
|
queryset=Device.objects.all(),
|
||||||
@ -1162,8 +1108,7 @@ class ConsoleConnectionFilterForm(FilterForm):
|
|||||||
query_params={
|
query_params={
|
||||||
'site_id': '$site_id'
|
'site_id': '$site_id'
|
||||||
},
|
},
|
||||||
label=_('Device'),
|
label=_('Device')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -1171,8 +1116,7 @@ class PowerConnectionFilterForm(FilterForm):
|
|||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Region'),
|
label=_('Region')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
site_id = DynamicModelMultipleChoiceField(
|
site_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
@ -1180,8 +1124,7 @@ class PowerConnectionFilterForm(FilterForm):
|
|||||||
query_params={
|
query_params={
|
||||||
'region_id': '$region_id'
|
'region_id': '$region_id'
|
||||||
},
|
},
|
||||||
label=_('Site'),
|
label=_('Site')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
device_id = DynamicModelMultipleChoiceField(
|
device_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Device.objects.all(),
|
queryset=Device.objects.all(),
|
||||||
@ -1189,8 +1132,7 @@ class PowerConnectionFilterForm(FilterForm):
|
|||||||
query_params={
|
query_params={
|
||||||
'site_id': '$site_id'
|
'site_id': '$site_id'
|
||||||
},
|
},
|
||||||
label=_('Device'),
|
label=_('Device')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -1198,8 +1140,7 @@ class InterfaceConnectionFilterForm(FilterForm):
|
|||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Region'),
|
label=_('Region')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
site_id = DynamicModelMultipleChoiceField(
|
site_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
@ -1207,8 +1148,7 @@ class InterfaceConnectionFilterForm(FilterForm):
|
|||||||
query_params={
|
query_params={
|
||||||
'region_id': '$region_id'
|
'region_id': '$region_id'
|
||||||
},
|
},
|
||||||
label=_('Site'),
|
label=_('Site')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
device_id = DynamicModelMultipleChoiceField(
|
device_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Device.objects.all(),
|
queryset=Device.objects.all(),
|
||||||
@ -1216,6 +1156,5 @@ class InterfaceConnectionFilterForm(FilterForm):
|
|||||||
query_params={
|
query_params={
|
||||||
'site_id': '$site_id'
|
'site_id': '$site_id'
|
||||||
},
|
},
|
||||||
label=_('Device'),
|
label=_('Device')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
|
@ -300,16 +300,14 @@ class RackReservationForm(TenancyForm, CustomFieldModelForm):
|
|||||||
required=False,
|
required=False,
|
||||||
initial_params={
|
initial_params={
|
||||||
'sites': '$site'
|
'sites': '$site'
|
||||||
},
|
}
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
site_group = DynamicModelChoiceField(
|
site_group = DynamicModelChoiceField(
|
||||||
queryset=SiteGroup.objects.all(),
|
queryset=SiteGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
initial_params={
|
initial_params={
|
||||||
'sites': '$site'
|
'sites': '$site'
|
||||||
},
|
}
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
site = DynamicModelChoiceField(
|
site = DynamicModelChoiceField(
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
@ -317,24 +315,21 @@ class RackReservationForm(TenancyForm, CustomFieldModelForm):
|
|||||||
query_params={
|
query_params={
|
||||||
'region_id': '$region',
|
'region_id': '$region',
|
||||||
'group_id': '$site_group',
|
'group_id': '$site_group',
|
||||||
},
|
}
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
location = DynamicModelChoiceField(
|
location = DynamicModelChoiceField(
|
||||||
queryset=Location.objects.all(),
|
queryset=Location.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
query_params={
|
query_params={
|
||||||
'site_id': '$site'
|
'site_id': '$site'
|
||||||
},
|
}
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
rack = DynamicModelChoiceField(
|
rack = DynamicModelChoiceField(
|
||||||
queryset=Rack.objects.all(),
|
queryset=Rack.objects.all(),
|
||||||
query_params={
|
query_params={
|
||||||
'site_id': '$site',
|
'site_id': '$site',
|
||||||
'location_id': '$location',
|
'location_id': '$location',
|
||||||
},
|
}
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
units = NumericArrayField(
|
units = NumericArrayField(
|
||||||
base_field=forms.IntegerField(),
|
base_field=forms.IntegerField(),
|
||||||
@ -348,8 +343,7 @@ class RackReservationForm(TenancyForm, CustomFieldModelForm):
|
|||||||
)
|
)
|
||||||
tags = DynamicModelMultipleChoiceField(
|
tags = DynamicModelMultipleChoiceField(
|
||||||
queryset=Tag.objects.all(),
|
queryset=Tag.objects.all(),
|
||||||
required=False,
|
required=False
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -3,9 +3,10 @@ from django.contrib.contenttypes.models import ContentType
|
|||||||
from django.contrib.postgres.forms import SimpleArrayField
|
from django.contrib.postgres.forms import SimpleArrayField
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
|
|
||||||
|
from extras.choices import CustomFieldTypeChoices
|
||||||
from extras.models import *
|
from extras.models import *
|
||||||
from extras.utils import FeatureQuery
|
from extras.utils import FeatureQuery
|
||||||
from utilities.forms import CSVContentTypeField, CSVModelForm, CSVMultipleContentTypeField, SlugField
|
from utilities.forms import CSVChoiceField, CSVContentTypeField, CSVModelForm, CSVMultipleContentTypeField, SlugField
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'CustomFieldCSVForm',
|
'CustomFieldCSVForm',
|
||||||
@ -22,6 +23,10 @@ class CustomFieldCSVForm(CSVModelForm):
|
|||||||
limit_choices_to=FeatureQuery('custom_fields'),
|
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.)'
|
||||||
|
)
|
||||||
choices = SimpleArrayField(
|
choices = SimpleArrayField(
|
||||||
base_field=forms.CharField(),
|
base_field=forms.CharField(),
|
||||||
required=False,
|
required=False,
|
||||||
@ -32,7 +37,7 @@ class CustomFieldCSVForm(CSVModelForm):
|
|||||||
model = CustomField
|
model = CustomField
|
||||||
fields = (
|
fields = (
|
||||||
'name', 'label', 'type', 'content_types', 'required', 'description', 'weight', 'filter_logic', 'default',
|
'name', 'label', 'type', 'content_types', 'required', 'description', 'weight', 'filter_logic', 'default',
|
||||||
'choices', 'weight',
|
'choices', 'weight', 'validation_minimum', 'validation_maximum', 'validation_regex',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -164,38 +164,32 @@ class ConfigContextFilterForm(FilterForm):
|
|||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Regions'),
|
label=_('Regions')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
site_group_id = DynamicModelMultipleChoiceField(
|
site_group_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=SiteGroup.objects.all(),
|
queryset=SiteGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Site groups'),
|
label=_('Site groups')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
site_id = DynamicModelMultipleChoiceField(
|
site_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Sites'),
|
label=_('Sites')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
device_type_id = DynamicModelMultipleChoiceField(
|
device_type_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=DeviceType.objects.all(),
|
queryset=DeviceType.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Device types'),
|
label=_('Device types')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
role_id = DynamicModelMultipleChoiceField(
|
role_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=DeviceRole.objects.all(),
|
queryset=DeviceRole.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Roles'),
|
label=_('Roles')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
platform_id = DynamicModelMultipleChoiceField(
|
platform_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Platform.objects.all(),
|
queryset=Platform.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Platforms'),
|
label=_('Platforms')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
cluster_type_id = DynamicModelMultipleChoiceField(
|
cluster_type_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=ClusterType.objects.all(),
|
queryset=ClusterType.objects.all(),
|
||||||
@ -206,33 +200,28 @@ class ConfigContextFilterForm(FilterForm):
|
|||||||
cluster_group_id = DynamicModelMultipleChoiceField(
|
cluster_group_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=ClusterGroup.objects.all(),
|
queryset=ClusterGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Cluster groups'),
|
label=_('Cluster groups')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
cluster_id = DynamicModelMultipleChoiceField(
|
cluster_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Cluster.objects.all(),
|
queryset=Cluster.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Clusters'),
|
label=_('Clusters')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
tenant_group_id = DynamicModelMultipleChoiceField(
|
tenant_group_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=TenantGroup.objects.all(),
|
queryset=TenantGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Tenant groups'),
|
label=_('Tenant groups')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
tenant_id = DynamicModelMultipleChoiceField(
|
tenant_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Tenant.objects.all(),
|
queryset=Tenant.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Tenant'),
|
label=_('Tenant')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
tag = DynamicModelMultipleChoiceField(
|
tag = DynamicModelMultipleChoiceField(
|
||||||
queryset=Tag.objects.all(),
|
queryset=Tag.objects.all(),
|
||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Tags'),
|
label=_('Tags')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -269,8 +258,7 @@ class JournalEntryFilterForm(FilterForm):
|
|||||||
label=_('User'),
|
label=_('User'),
|
||||||
widget=APISelectMultiple(
|
widget=APISelectMultiple(
|
||||||
api_url='/api/users/users/',
|
api_url='/api/users/users/',
|
||||||
),
|
)
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
assigned_object_type_id = DynamicModelMultipleChoiceField(
|
assigned_object_type_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=ContentType.objects.all(),
|
queryset=ContentType.objects.all(),
|
||||||
@ -278,8 +266,7 @@ class JournalEntryFilterForm(FilterForm):
|
|||||||
label=_('Object Type'),
|
label=_('Object Type'),
|
||||||
widget=APISelectMultiple(
|
widget=APISelectMultiple(
|
||||||
api_url='/api/extras/content-types/',
|
api_url='/api/extras/content-types/',
|
||||||
),
|
)
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
kind = forms.ChoiceField(
|
kind = forms.ChoiceField(
|
||||||
choices=add_blank_choice(JournalEntryKindChoices),
|
choices=add_blank_choice(JournalEntryKindChoices),
|
||||||
@ -316,8 +303,7 @@ class ObjectChangeFilterForm(FilterForm):
|
|||||||
label=_('User'),
|
label=_('User'),
|
||||||
widget=APISelectMultiple(
|
widget=APISelectMultiple(
|
||||||
api_url='/api/users/users/',
|
api_url='/api/users/users/',
|
||||||
),
|
)
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
changed_object_type_id = DynamicModelMultipleChoiceField(
|
changed_object_type_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=ContentType.objects.all(),
|
queryset=ContentType.objects.all(),
|
||||||
@ -325,6 +311,5 @@ class ObjectChangeFilterForm(FilterForm):
|
|||||||
label=_('Object Type'),
|
label=_('Object Type'),
|
||||||
widget=APISelectMultiple(
|
widget=APISelectMultiple(
|
||||||
api_url='/api/extras/content-types/',
|
api_url='/api/extras/content-types/',
|
||||||
),
|
)
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
|
@ -39,10 +39,10 @@ class CustomFieldTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|||||||
}
|
}
|
||||||
|
|
||||||
cls.csv_data = (
|
cls.csv_data = (
|
||||||
'name,label,type,content_types,weight,filter_logic,choices',
|
'name,label,type,content_types,weight,filter_logic,choices,validation_minimum,validation_maximum,validation_regex',
|
||||||
'field4,Field 4,text,dcim.site,100,exact,',
|
'field4,Field 4,text,dcim.site,100,exact,,,,[a-z]{3}',
|
||||||
'field5,Field 5,integer,dcim.site,100,exact,',
|
'field5,Field 5,integer,dcim.site,100,exact,,1,100,',
|
||||||
'field6,Field 6,select,dcim.site,100,exact,"A,B,C"',
|
'field6,Field 6,select,dcim.site,100,exact,"A,B,C",,,',
|
||||||
)
|
)
|
||||||
|
|
||||||
cls.bulk_edit_data = {
|
cls.bulk_edit_data = {
|
||||||
|
@ -48,14 +48,12 @@ class VRFFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
import_target_id = DynamicModelMultipleChoiceField(
|
import_target_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=RouteTarget.objects.all(),
|
queryset=RouteTarget.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Import targets'),
|
label=_('Import targets')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
export_target_id = DynamicModelMultipleChoiceField(
|
export_target_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=RouteTarget.objects.all(),
|
queryset=RouteTarget.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Export targets'),
|
label=_('Export targets')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
@ -70,14 +68,12 @@ class RouteTargetFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
importing_vrf_id = DynamicModelMultipleChoiceField(
|
importing_vrf_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=VRF.objects.all(),
|
queryset=VRF.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Imported by VRF'),
|
label=_('Imported by VRF')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
exporting_vrf_id = DynamicModelMultipleChoiceField(
|
exporting_vrf_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=VRF.objects.all(),
|
queryset=VRF.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Exported by VRF'),
|
label=_('Exported by VRF')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
@ -110,8 +106,7 @@ class AggregateFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
rir_id = DynamicModelMultipleChoiceField(
|
rir_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=RIR.objects.all(),
|
queryset=RIR.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('RIR'),
|
label=_('RIR')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
@ -127,14 +122,12 @@ class ASNFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
rir_id = DynamicModelMultipleChoiceField(
|
rir_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=RIR.objects.all(),
|
queryset=RIR.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('RIR'),
|
label=_('RIR')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
site_id = DynamicModelMultipleChoiceField(
|
site_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Site'),
|
label=_('Site')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -180,14 +173,12 @@ class PrefixFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
queryset=VRF.objects.all(),
|
queryset=VRF.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Assigned VRF'),
|
label=_('Assigned VRF'),
|
||||||
null_option='Global',
|
null_option='Global'
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
present_in_vrf_id = DynamicModelChoiceField(
|
present_in_vrf_id = DynamicModelChoiceField(
|
||||||
queryset=VRF.objects.all(),
|
queryset=VRF.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Present in VRF'),
|
label=_('Present in VRF')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
status = forms.MultipleChoiceField(
|
status = forms.MultipleChoiceField(
|
||||||
choices=PrefixStatusChoices,
|
choices=PrefixStatusChoices,
|
||||||
@ -197,14 +188,12 @@ class PrefixFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Region'),
|
label=_('Region')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
site_group_id = DynamicModelMultipleChoiceField(
|
site_group_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=SiteGroup.objects.all(),
|
queryset=SiteGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Site group'),
|
label=_('Site group')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
site_id = DynamicModelMultipleChoiceField(
|
site_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
@ -213,15 +202,13 @@ class PrefixFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
query_params={
|
query_params={
|
||||||
'region_id': '$region_id'
|
'region_id': '$region_id'
|
||||||
},
|
},
|
||||||
label=_('Site'),
|
label=_('Site')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
role_id = DynamicModelMultipleChoiceField(
|
role_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Role.objects.all(),
|
queryset=Role.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
null_option='None',
|
null_option='None',
|
||||||
label=_('Role'),
|
label=_('Role')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
is_pool = forms.NullBooleanField(
|
is_pool = forms.NullBooleanField(
|
||||||
required=False,
|
required=False,
|
||||||
@ -257,8 +244,7 @@ class IPRangeFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
queryset=VRF.objects.all(),
|
queryset=VRF.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Assigned VRF'),
|
label=_('Assigned VRF'),
|
||||||
null_option='Global',
|
null_option='Global'
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
status = forms.MultipleChoiceField(
|
status = forms.MultipleChoiceField(
|
||||||
choices=PrefixStatusChoices,
|
choices=PrefixStatusChoices,
|
||||||
@ -269,8 +255,7 @@ class IPRangeFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
queryset=Role.objects.all(),
|
queryset=Role.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
null_option='None',
|
null_option='None',
|
||||||
label=_('Role'),
|
label=_('Role')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
@ -308,14 +293,12 @@ class IPAddressFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
queryset=VRF.objects.all(),
|
queryset=VRF.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Assigned VRF'),
|
label=_('Assigned VRF'),
|
||||||
null_option='Global',
|
null_option='Global'
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
present_in_vrf_id = DynamicModelChoiceField(
|
present_in_vrf_id = DynamicModelChoiceField(
|
||||||
queryset=VRF.objects.all(),
|
queryset=VRF.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Present in VRF'),
|
label=_('Present in VRF')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
status = forms.MultipleChoiceField(
|
status = forms.MultipleChoiceField(
|
||||||
choices=IPAddressStatusChoices,
|
choices=IPAddressStatusChoices,
|
||||||
@ -377,32 +360,27 @@ class VLANGroupFilterForm(CustomFieldModelFilterForm):
|
|||||||
region = DynamicModelMultipleChoiceField(
|
region = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Region'),
|
label=_('Region')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
sitegroup = DynamicModelMultipleChoiceField(
|
sitegroup = DynamicModelMultipleChoiceField(
|
||||||
queryset=SiteGroup.objects.all(),
|
queryset=SiteGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Site group'),
|
label=_('Site group')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
site = DynamicModelMultipleChoiceField(
|
site = DynamicModelMultipleChoiceField(
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Site'),
|
label=_('Site')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
location = DynamicModelMultipleChoiceField(
|
location = DynamicModelMultipleChoiceField(
|
||||||
queryset=Location.objects.all(),
|
queryset=Location.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Location'),
|
label=_('Location')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
rack = DynamicModelMultipleChoiceField(
|
rack = DynamicModelMultipleChoiceField(
|
||||||
queryset=Rack.objects.all(),
|
queryset=Rack.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Rack'),
|
label=_('Rack')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
min_vid = forms.IntegerField(
|
min_vid = forms.IntegerField(
|
||||||
min_value=VLAN_VID_MIN,
|
min_value=VLAN_VID_MIN,
|
||||||
@ -426,14 +404,12 @@ class VLANFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Region'),
|
label=_('Region')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
site_group_id = DynamicModelMultipleChoiceField(
|
site_group_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=SiteGroup.objects.all(),
|
queryset=SiteGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Site group'),
|
label=_('Site group')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
site_id = DynamicModelMultipleChoiceField(
|
site_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
@ -442,8 +418,7 @@ class VLANFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
query_params={
|
query_params={
|
||||||
'region': '$region'
|
'region': '$region'
|
||||||
},
|
},
|
||||||
label=_('Site'),
|
label=_('Site')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
group_id = DynamicModelMultipleChoiceField(
|
group_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=VLANGroup.objects.all(),
|
queryset=VLANGroup.objects.all(),
|
||||||
@ -452,8 +427,7 @@ class VLANFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
query_params={
|
query_params={
|
||||||
'region': '$region'
|
'region': '$region'
|
||||||
},
|
},
|
||||||
label=_('VLAN group'),
|
label=_('VLAN group')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
status = forms.MultipleChoiceField(
|
status = forms.MultipleChoiceField(
|
||||||
choices=VLANStatusChoices,
|
choices=VLANStatusChoices,
|
||||||
@ -464,8 +438,7 @@ class VLANFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
queryset=Role.objects.all(),
|
queryset=Role.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
null_option='None',
|
null_option='None',
|
||||||
label=_('Role'),
|
label=_('Role')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
vid = forms.IntegerField(
|
vid = forms.IntegerField(
|
||||||
required=False,
|
required=False,
|
||||||
|
@ -418,7 +418,7 @@ class PrefixView(generic.ObjectView):
|
|||||||
).filter(
|
).filter(
|
||||||
prefix__net_contains=str(instance.prefix)
|
prefix__net_contains=str(instance.prefix)
|
||||||
).prefetch_related(
|
).prefetch_related(
|
||||||
'site', 'role'
|
'site', 'role', 'tenant'
|
||||||
)
|
)
|
||||||
parent_prefix_table = tables.PrefixTable(
|
parent_prefix_table = tables.PrefixTable(
|
||||||
list(parent_prefixes),
|
list(parent_prefixes),
|
||||||
|
BIN
netbox/project-static/dist/netbox.js
vendored
BIN
netbox/project-static/dist/netbox.js
vendored
Binary file not shown.
@ -251,7 +251,7 @@ export class APISelect {
|
|||||||
} else if (collapse !== null) {
|
} else if (collapse !== null) {
|
||||||
this.trigger = 'collapse';
|
this.trigger = 'collapse';
|
||||||
} else {
|
} else {
|
||||||
this.trigger = 'load';
|
this.trigger = 'open';
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (this.trigger) {
|
switch (this.trigger) {
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{# Top bar #}
|
{# Top bar #}
|
||||||
<nav class="navbar navbar-light sticky-top flex-md-nowrap p-1 mb-3 search container-fluid border-bottom bg-light bg-gradient noprint">
|
<nav class="navbar navbar-light sticky-top flex-md-nowrap p-1 mb-3 search container-fluid border-bottom noprint">
|
||||||
|
|
||||||
{# Mobile Navigation #}
|
{# Mobile Navigation #}
|
||||||
<div class="nav-mobile">
|
<div class="nav-mobile">
|
||||||
|
@ -40,13 +40,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">VM Role</th>
|
<th scope="row">VM Role</th>
|
||||||
<td>
|
<td>{% checkmark object.vm_role %}</td>
|
||||||
{% if object.vm_role %}
|
|
||||||
<i class="mdi mdi-check-bold text-success" title="Yes"></i>
|
|
||||||
{% else %}
|
|
||||||
<i class="mdi mdi-close-thick text-danger" title="No"></i>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Devices</th>
|
<th scope="row">Devices</th>
|
||||||
|
@ -33,13 +33,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Full Depth</td>
|
<td>Full Depth</td>
|
||||||
<td>
|
<td>{% checkmark object.is_full_depth %}</td>
|
||||||
{% if object.is_full_depth %}
|
|
||||||
<i class="mdi mdi-check-bold text-success" title="Yes"></i>
|
|
||||||
{% else %}
|
|
||||||
<i class="mdi mdi-close-thick text-danger" title="No"></i>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Parent/Child</td>
|
<td>Parent/Child</td>
|
||||||
|
@ -48,23 +48,11 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Enabled</th>
|
<th scope="row">Enabled</th>
|
||||||
<td>
|
<td>{% checkmark object.enabled %}</td>
|
||||||
{% if object.enabled %}
|
|
||||||
<i class="mdi mdi-check-bold text-success" title="Yes"></i>
|
|
||||||
{% else %}
|
|
||||||
<i class="mdi mdi-close-thick text-danger" title="No"></i>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Management Only</th>
|
<th scope="row">Management Only</th>
|
||||||
<td>
|
<td>{% checkmark object.mgmt_only %}</td>
|
||||||
{% if object.mgmt_only %}
|
|
||||||
<i class="mdi mdi-check-bold text-success" title="Yes"></i>
|
|
||||||
{% else %}
|
|
||||||
<i class="mdi mdi-close-thick text-danger" title="No"></i>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Parent</th>
|
<th scope="row">Parent</th>
|
||||||
|
@ -65,7 +65,7 @@
|
|||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{% if object.master == vc_member %}
|
{% if object.master == vc_member %}
|
||||||
<i class="mdi mdi-check-bold text-success"></i>
|
{% checkmark True %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
@ -29,13 +29,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Required</th>
|
<th scope="row">Required</th>
|
||||||
<td>
|
<td>{% checkmark object.required %}</td>
|
||||||
{% if object.required %}
|
|
||||||
<i class="mdi mdi-check-bold text-success" title="Yes"></i>
|
|
||||||
{% else %}
|
|
||||||
<i class="mdi mdi-close-thick text-danger" title="No"></i>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Weight</th>
|
<th scope="row">Weight</th>
|
||||||
|
@ -33,13 +33,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">New Window</th>
|
<th scope="row">New Window</th>
|
||||||
<td>
|
<td>{% checkmark object.new_window %}</td>
|
||||||
{% if object.new_window %}
|
|
||||||
<i class="mdi mdi-check-bold text-success" title="Yes"></i>
|
|
||||||
{% else %}
|
|
||||||
<i class="mdi mdi-close-thick text-danger" title="No"></i>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
@ -40,13 +40,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Attachment</th>
|
<th scope="row">Attachment</th>
|
||||||
<td>
|
<td>{% checkmark object.as_attachment %}</td>
|
||||||
{% if object.as_attachment %}
|
|
||||||
<i class="mdi mdi-check-bold text-success" title="Yes"></i>
|
|
||||||
{% else %}
|
|
||||||
<i class="mdi mdi-close-thick text-danger" title="No"></i>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
@ -17,13 +17,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Enabled</th>
|
<th scope="row">Enabled</th>
|
||||||
<td>
|
<td>{% checkmark object.enabled %}</td>
|
||||||
{% if object.enabled %}
|
|
||||||
<i class="mdi mdi-check-bold text-success" title="Yes"></i>
|
|
||||||
{% else %}
|
|
||||||
<i class="mdi mdi-close-thick text-danger" title="No"></i>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@ -36,33 +30,15 @@
|
|||||||
<table class="table table-hover attr-table">
|
<table class="table table-hover attr-table">
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Create</th>
|
<th scope="row">Create</th>
|
||||||
<td>
|
<td>{% checkmark object.type_create %}</td>
|
||||||
{% if object.type_create %}
|
|
||||||
<i class="mdi mdi-check-bold text-success" title="Yes"></i>
|
|
||||||
{% else %}
|
|
||||||
<i class="mdi mdi-close-thick text-danger" title="No"></i>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Update</th>
|
<th scope="row">Update</th>
|
||||||
<td>
|
<td>{% checkmark object.type_update %}</td>
|
||||||
{% if object.type_update %}
|
|
||||||
<i class="mdi mdi-check-bold text-success" title="Yes"></i>
|
|
||||||
{% else %}
|
|
||||||
<i class="mdi mdi-close-thick text-danger" title="No"></i>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Delete</th>
|
<th scope="row">Delete</th>
|
||||||
<td>
|
<td>{% checkmark object.type_delete %}</td>
|
||||||
{% if object.type_delete %}
|
|
||||||
<i class="mdi mdi-check-bold text-success" title="Yes"></i>
|
|
||||||
{% else %}
|
|
||||||
<i class="mdi mdi-close-thick text-danger" title="No"></i>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@ -100,13 +76,7 @@
|
|||||||
<table class="table table-hover attr-table">
|
<table class="table table-hover attr-table">
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">SSL Verification</th>
|
<th scope="row">SSL Verification</th>
|
||||||
<td>
|
<td>{% checkmark object.ssl_verification %}</td>
|
||||||
{% if object.ssl_verification %}
|
|
||||||
<i class="mdi mdi-check-bold text-success" title="Yes"></i>
|
|
||||||
{% else %}
|
|
||||||
<i class="mdi mdi-close-thick text-danger" title="No"></i>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">CA File Path</th>
|
<th scope="row">CA File Path</th>
|
||||||
|
@ -66,7 +66,7 @@
|
|||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{% if field.required %}
|
{% if field.required %}
|
||||||
<i class="mdi mdi-check-bold text-success" title="Required"></i>
|
{% checkmark True true="Required" %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<span class="text-muted">—</span>
|
<span class="text-muted">—</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -15,9 +15,9 @@
|
|||||||
{% if field.type == 'longtext' and value %}
|
{% if field.type == 'longtext' and value %}
|
||||||
{{ value|render_markdown }}
|
{{ value|render_markdown }}
|
||||||
{% elif field.type == 'boolean' and value == True %}
|
{% elif field.type == 'boolean' and value == True %}
|
||||||
<i class="mdi mdi-check-bold text-success" title="True"></i>
|
{% checkmark value true="True" %}
|
||||||
{% elif field.type == 'boolean' and value == False %}
|
{% elif field.type == 'boolean' and value == False %}
|
||||||
<i class="mdi mdi-close-thick text-danger" title="False"></i>
|
{% checkmark value false="False" %}
|
||||||
{% elif field.type == 'url' and value %}
|
{% elif field.type == 'url' and value %}
|
||||||
<a href="{{ value }}">{{ value|truncatechars:70 }}</a>
|
<a href="{{ value }}">{{ value|truncatechars:70 }}</a>
|
||||||
{% elif field.type == 'json' and value %}
|
{% elif field.type == 'json' and value %}
|
||||||
|
@ -4,127 +4,154 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col col-md-6">
|
<div class="col col-md-6">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h5 class="card-header">
|
<h5 class="card-header">Prefix</h5>
|
||||||
Prefix
|
<div class="card-body">
|
||||||
</h5>
|
<table class="table table-hover attr-table">
|
||||||
<div class="card-body">
|
<tr>
|
||||||
<table class="table table-hover attr-table">
|
<th scope="row">Family</th>
|
||||||
<tr>
|
<td>IPv{{ object.family }}</td>
|
||||||
<th scope="row">Family</th>
|
</tr>
|
||||||
<td>IPv{{ object.family }}</td>
|
<tr>
|
||||||
</tr>
|
<th scope="row">VRF</th>
|
||||||
<tr>
|
<td>
|
||||||
<th scope="row">VRF</th>
|
{% if object.vrf %}
|
||||||
<td>
|
<a href="{% url 'ipam:vrf' pk=object.vrf.pk %}">{{ object.vrf }}</a> ({{ object.vrf.rd }})
|
||||||
{% if object.vrf %}
|
{% else %}
|
||||||
<a href="{% url 'ipam:vrf' pk=object.vrf.pk %}">{{ object.vrf }}</a> ({{ object.vrf.rd }})
|
<span>Global</span>
|
||||||
{% else %}
|
{% endif %}
|
||||||
<span>Global</span>
|
</td>
|
||||||
{% endif %}
|
</tr>
|
||||||
</td>
|
<tr>
|
||||||
</tr>
|
<th scope="row">Tenant</th>
|
||||||
<tr>
|
<td>
|
||||||
<th scope="row">Tenant</th>
|
{% if object.tenant %}
|
||||||
<td>
|
{% if object.tenant.group %}
|
||||||
{% if object.tenant %}
|
<a href="{{ object.tenant.group.get_absolute_url }}">{{ object.tenant.group }}</a> /
|
||||||
{% if object.tenant.group %}
|
{% endif %}
|
||||||
<a href="{{ object.tenant.group.get_absolute_url }}">{{ object.tenant.group }}</a> /
|
<a href="{{ object.tenant.get_absolute_url }}">{{ object.tenant }}</a>
|
||||||
{% endif %}
|
{% else %}
|
||||||
<a href="{{ object.tenant.get_absolute_url }}">{{ object.tenant }}</a>
|
<span class="text-muted">None</span>
|
||||||
{% else %}
|
{% endif %}
|
||||||
<span class="text-muted">None</span>
|
</td>
|
||||||
{% endif %}
|
</tr>
|
||||||
</td>
|
<tr>
|
||||||
</tr>
|
<th scope="row">Aggregate</th>
|
||||||
<tr>
|
<td>
|
||||||
<th scope="row">Aggregate</th>
|
{% if aggregate %}
|
||||||
<td>
|
<a href="{% url 'ipam:aggregate' pk=aggregate.pk %}">{{ aggregate.prefix }}</a> ({{ aggregate.rir }})
|
||||||
{% if aggregate %}
|
{% else %}
|
||||||
<a href="{% url 'ipam:aggregate' pk=aggregate.pk %}">{{ aggregate.prefix }}</a> ({{ aggregate.rir }})
|
<span class="text-warning">None</span>
|
||||||
{% else %}
|
{% endif %}
|
||||||
<span class="text-warning">None</span>
|
</td>
|
||||||
{% endif %}
|
</tr>
|
||||||
</td>
|
<tr>
|
||||||
</tr>
|
<th scope="row">Site</th>
|
||||||
<tr>
|
<td>
|
||||||
<th scope="row">Site</th>
|
{% if object.site %}
|
||||||
<td>
|
{% if object.site.region %}
|
||||||
{% if object.site %}
|
<a href="{{ object.site.region.get_absolute_url }}">{{ object.site.region }}</a> /
|
||||||
{% if object.site.region %}
|
{% endif %}
|
||||||
<a href="{{ object.site.region.get_absolute_url }}">{{ object.site.region }}</a> /
|
<a href="{{ object.site.get_absolute_url }}">{{ object.site }}</a>
|
||||||
{% endif %}
|
{% else %}
|
||||||
<a href="{{ object.site.get_absolute_url }}">{{ object.site }}</a>
|
<span class="text-muted">None</span>
|
||||||
{% else %}
|
{% endif %}
|
||||||
<span class="text-muted">None</span>
|
</td>
|
||||||
{% endif %}
|
</tr>
|
||||||
</td>
|
<tr>
|
||||||
</tr>
|
<th scope="row">VLAN</th>
|
||||||
<tr>
|
<td>
|
||||||
<th scope="row">VLAN</th>
|
{% if object.vlan %}
|
||||||
<td>
|
{% if object.vlan.group %}
|
||||||
{% if object.vlan %}
|
<a href="{{ object.vlan.group.get_absolute_url }}">{{ object.vlan.group }}</a> /
|
||||||
{% if object.vlan.group %}
|
{% endif %}
|
||||||
<a href="{{ object.vlan.group.get_absolute_url }}">{{ object.vlan.group }}</a> /
|
<a href="{% url 'ipam:vlan' pk=object.vlan.pk %}">{{ object.vlan }}</a>
|
||||||
{% endif %}
|
{% else %}
|
||||||
<a href="{% url 'ipam:vlan' pk=object.vlan.pk %}">{{ object.vlan }}</a>
|
<span class="text-muted">None</span>
|
||||||
{% else %}
|
{% endif %}
|
||||||
<span class="text-muted">None</span>
|
</td>
|
||||||
{% endif %}
|
</tr>
|
||||||
</td>
|
<tr>
|
||||||
</tr>
|
<th scope="row">Status</th>
|
||||||
<tr>
|
<td>
|
||||||
<th scope="row">Status</th>
|
<span class="badge bg-{{ object.get_status_class }}">{{ object.get_status_display }}</span>
|
||||||
<td>
|
</td>
|
||||||
<span class="badge bg-{{ object.get_status_class }}">{{ object.get_status_display }}</span>
|
</tr>
|
||||||
</td>
|
<tr>
|
||||||
</tr>
|
<th scope="row">Role</th>
|
||||||
<tr>
|
<td>
|
||||||
<th scope="row">Role</th>
|
{% if object.role %}
|
||||||
<td>
|
<a href="{{ object.role.get_absolute_url }}">{{ object.role }}</a>
|
||||||
{% if object.role %}
|
{% else %}
|
||||||
<a href="{{ object.role.get_absolute_url }}">{{ object.role }}</a>
|
<span class="text-muted">None</span>
|
||||||
{% else %}
|
{% endif %}
|
||||||
<span class="text-muted">None</span>
|
</td>
|
||||||
{% endif %}
|
</tr>
|
||||||
</td>
|
<tr>
|
||||||
</tr>
|
<th scope="row">Description</th>
|
||||||
<tr>
|
<td>{{ object.description|placeholder }}</td>
|
||||||
<th scope="row">Description</th>
|
</tr>
|
||||||
<td>{{ object.description|placeholder }}</td>
|
<tr>
|
||||||
</tr>
|
<th scope="row">Is a pool</th>
|
||||||
<tr>
|
<td>{% checkmark object.is_pool %}</td>
|
||||||
<th scope="row">Is a pool</th>
|
</tr>
|
||||||
<td>
|
</table>
|
||||||
{% if object.is_pool %}
|
</div>
|
||||||
<i class="mdi mdi-check-bold text-success" title="Yes"></i>
|
|
||||||
{% else %}
|
|
||||||
<i class="mdi mdi-close-thick text-danger" title="No"></i>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th scope="row">Utilization</th>
|
|
||||||
<td>
|
|
||||||
{% if object.mark_utilized %}
|
|
||||||
{% utilization_graph 100 warning_threshold=0 danger_threshold=0 %}
|
|
||||||
<small>(Marked fully utilized)</small>
|
|
||||||
{% else %}
|
|
||||||
{% utilization_graph object.get_utilization %}
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% plugin_left_page object %}
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col col-md-6">
|
{% plugin_left_page object %}
|
||||||
{% include 'inc/panels/custom_fields.html' %}
|
</div>
|
||||||
{% include 'inc/panels/tags.html' %}
|
<div class="col col-md-6">
|
||||||
{% plugin_right_page object %}
|
<div class="card">
|
||||||
|
<h5 class="card-header">Addressing</h5>
|
||||||
|
<div class="card-body">
|
||||||
|
<table class="table table-hover attr-table">
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Utilization</th>
|
||||||
|
<td>
|
||||||
|
{% if object.mark_utilized %}
|
||||||
|
{% utilization_graph 100 warning_threshold=0 danger_threshold=0 %}
|
||||||
|
<small>(Marked fully utilized)</small>
|
||||||
|
{% else %}
|
||||||
|
{% utilization_graph object.get_utilization %}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% with child_ip_count=object.get_child_ips.count %}
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Child IPs</th>
|
||||||
|
<td>
|
||||||
|
<a href="{% url 'ipam:prefix_ipaddresses' pk=object.pk %}">{{ child_ip_count }}</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Available IPs</th>
|
||||||
|
<td>{{ object.get_available_ips|length }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endwith %}
|
||||||
|
<tr>
|
||||||
|
<td>First available IP</td>
|
||||||
|
<td>
|
||||||
|
{% with first_available_ip=object.get_first_available_ip %}
|
||||||
|
{% if first_available_ip %}
|
||||||
|
{% if perms.ipam.add_ipaddress %}
|
||||||
|
<a href="{% url 'ipam:ipaddress_add' %}?address={{ first_available_ip }}">{{ first_available_ip }}</a>
|
||||||
|
{% else %}
|
||||||
|
{{ first_available_ip }}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
<span class="text-muted">None</span>
|
||||||
|
{% endif %}
|
||||||
|
{% endwith %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% include 'inc/panels/custom_fields.html' %}
|
||||||
|
{% include 'inc/panels/tags.html' %}
|
||||||
|
{% plugin_right_page object %}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col col-md-12">
|
<div class="col col-md-12">
|
||||||
|
@ -30,13 +30,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Private</th>
|
<th scope="row">Private</th>
|
||||||
<td>
|
<td>{% checkmark object.is_private %}</td>
|
||||||
{% if object.is_private %}
|
|
||||||
<i class="mdi mdi-check-bold text-success" title="Yes"></i>
|
|
||||||
{% else %}
|
|
||||||
<i class="mdi mdi-close-thick text-danger" title="No"></i>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Aggregates</th>
|
<th scope="row">Aggregates</th>
|
||||||
|
@ -30,13 +30,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Unique IP Space</th>
|
<th scope="row">Unique IP Space</th>
|
||||||
<td>
|
<td>{% checkmark object.enforce_unique %}</td>
|
||||||
{% if object.enforce_unique %}
|
|
||||||
<i class="mdi mdi-check-bold text-success" title="Yes"></i>
|
|
||||||
{% else %}
|
|
||||||
<i class="mdi mdi-close-thick text-danger" title="No"></i>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Description</th>
|
<th scope="row">Description</th>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col col-md-12">
|
<div class="col col-md-10 offset-md-1">
|
||||||
{% for token in tokens %}
|
{% for token in tokens %}
|
||||||
<div class="card{% if token.is_expired %} bg-danger{% endif %}">
|
<div class="card{% if token.is_expired %} bg-danger{% endif %}">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
@ -49,7 +49,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<p>You do not have any API tokens.</p>
|
<h6><i class="mdi mdi-information"></i> You do not have any API tokens.</h6>
|
||||||
|
<p>Tokens are used to authenticate REST and GraphQL API requests.</p>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<div class="text-end">
|
<div class="text-end">
|
||||||
<a href="{% url 'user:token_add' %}" class="btn btn-sm btn-primary my-3">
|
<a href="{% url 'user:token_add' %}" class="btn btn-sm btn-primary my-3">
|
||||||
|
@ -35,23 +35,11 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Superuser</th>
|
<th scope="row">Superuser</th>
|
||||||
<td>
|
<td>{% checkmark request.user.is_superuser %}</td>
|
||||||
{% if request.user.is_superuser %}
|
|
||||||
<i class="mdi mdi-check-bold text-success" title="Yes"></i>
|
|
||||||
{% else %}
|
|
||||||
<i class="mdi mdi-close-thick text-danger" title="No"></i>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Admin Access</th>
|
<th scope="row">Admin Access</th>
|
||||||
<td>
|
<td>{% checkmark request.user.is_staff %}</td>
|
||||||
{% if request.user.is_staff %}
|
|
||||||
<i class="mdi mdi-check-bold text-success" title="Yes"></i>
|
|
||||||
{% else %}
|
|
||||||
<i class="mdi mdi-close-thick text-danger" title="No"></i>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
@ -22,8 +22,7 @@ class TenantGroupFilterForm(CustomFieldModelFilterForm):
|
|||||||
parent_id = DynamicModelMultipleChoiceField(
|
parent_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=TenantGroup.objects.all(),
|
queryset=TenantGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Parent group'),
|
label=_('Parent group')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
@ -38,8 +37,7 @@ class TenantFilterForm(CustomFieldModelFilterForm):
|
|||||||
queryset=TenantGroup.objects.all(),
|
queryset=TenantGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
null_option='None',
|
null_option='None',
|
||||||
label=_('Group'),
|
label=_('Group')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
@ -53,8 +51,7 @@ class ContactGroupFilterForm(CustomFieldModelFilterForm):
|
|||||||
parent_id = DynamicModelMultipleChoiceField(
|
parent_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=ContactGroup.objects.all(),
|
queryset=ContactGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Parent group'),
|
label=_('Parent group')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
@ -74,7 +71,6 @@ class ContactFilterForm(CustomFieldModelFilterForm):
|
|||||||
queryset=ContactGroup.objects.all(),
|
queryset=ContactGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
null_option='None',
|
null_option='None',
|
||||||
label=_('Group'),
|
label=_('Group')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
@ -33,8 +33,7 @@ class TenancyFilterForm(forms.Form):
|
|||||||
queryset=TenantGroup.objects.all(),
|
queryset=TenantGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
null_option='None',
|
null_option='None',
|
||||||
label=_('Tenant group'),
|
label=_('Tenant group')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
tenant_id = DynamicModelMultipleChoiceField(
|
tenant_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Tenant.objects.all(),
|
queryset=Tenant.objects.all(),
|
||||||
@ -43,6 +42,5 @@ class TenancyFilterForm(forms.Form):
|
|||||||
query_params={
|
query_params={
|
||||||
'group_id': '$tenant_group_id'
|
'group_id': '$tenant_group_id'
|
||||||
},
|
},
|
||||||
label=_('Tenant'),
|
label=_('Tenant')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
|
@ -395,8 +395,8 @@ class DynamicModelChoiceMixin:
|
|||||||
filter = django_filters.ModelChoiceFilter
|
filter = django_filters.ModelChoiceFilter
|
||||||
widget = widgets.APISelect
|
widget = widgets.APISelect
|
||||||
|
|
||||||
def __init__(self, query_params=None, initial_params=None, null_option=None, disabled_indicator=None, fetch_trigger=None,
|
def __init__(self, query_params=None, initial_params=None, null_option=None, disabled_indicator=None,
|
||||||
empty_label=None, *args, **kwargs):
|
fetch_trigger=None, empty_label=None, *args, **kwargs):
|
||||||
self.query_params = query_params or {}
|
self.query_params = query_params or {}
|
||||||
self.initial_params = initial_params or {}
|
self.initial_params = initial_params or {}
|
||||||
self.null_option = null_option
|
self.null_option = null_option
|
||||||
|
5
netbox/utilities/templates/helpers/checkmark.html
Normal file
5
netbox/utilities/templates/helpers/checkmark.html
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{% if value %}
|
||||||
|
<i class="mdi mdi-check-bold text-success" title="{{ true_label }}"></i>
|
||||||
|
{% elif show_false %}
|
||||||
|
<i class="mdi mdi-close-thick text-danger" title="{{ false_label }}"></i>
|
||||||
|
{% endif %}
|
@ -426,6 +426,23 @@ def badge(value, bg_class='secondary', show_empty=False):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@register.inclusion_tag('helpers/checkmark.html')
|
||||||
|
def checkmark(value, show_false=True, true='Yes', false='No'):
|
||||||
|
"""
|
||||||
|
Display either a green checkmark or red X to indicate a boolean value.
|
||||||
|
|
||||||
|
:param show_false: Display a red X if the value is False
|
||||||
|
:param true: Text label for true value
|
||||||
|
:param false: Text label for false value
|
||||||
|
"""
|
||||||
|
return {
|
||||||
|
'value': bool(value),
|
||||||
|
'show_false': show_false,
|
||||||
|
'true_label': true,
|
||||||
|
'false_label': false,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@register.inclusion_tag('helpers/table_config_form.html')
|
@register.inclusion_tag('helpers/table_config_form.html')
|
||||||
def table_config_form(table, table_name=None):
|
def table_config_form(table, table_name=None):
|
||||||
return {
|
return {
|
||||||
|
@ -40,20 +40,17 @@ class ClusterFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
type_id = DynamicModelMultipleChoiceField(
|
type_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=ClusterType.objects.all(),
|
queryset=ClusterType.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Type'),
|
label=_('Type')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Region'),
|
label=_('Region')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
site_group_id = DynamicModelMultipleChoiceField(
|
site_group_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=SiteGroup.objects.all(),
|
queryset=SiteGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Site group'),
|
label=_('Site group')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
site_id = DynamicModelMultipleChoiceField(
|
site_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
@ -63,15 +60,13 @@ class ClusterFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
'region_id': '$region_id',
|
'region_id': '$region_id',
|
||||||
'site_group_id': '$site_group_id',
|
'site_group_id': '$site_group_id',
|
||||||
},
|
},
|
||||||
label=_('Site'),
|
label=_('Site')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
group_id = DynamicModelMultipleChoiceField(
|
group_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=ClusterGroup.objects.all(),
|
queryset=ClusterGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
null_option='None',
|
null_option='None',
|
||||||
label=_('Group'),
|
label=_('Group')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
@ -89,33 +84,28 @@ class VirtualMachineFilterForm(LocalConfigContextFilterForm, TenancyFilterForm,
|
|||||||
queryset=ClusterGroup.objects.all(),
|
queryset=ClusterGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
null_option='None',
|
null_option='None',
|
||||||
label=_('Cluster group'),
|
label=_('Cluster group')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
cluster_type_id = DynamicModelMultipleChoiceField(
|
cluster_type_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=ClusterType.objects.all(),
|
queryset=ClusterType.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
null_option='None',
|
null_option='None',
|
||||||
label=_('Cluster type'),
|
label=_('Cluster type')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
cluster_id = DynamicModelMultipleChoiceField(
|
cluster_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Cluster.objects.all(),
|
queryset=Cluster.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Cluster'),
|
label=_('Cluster')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Region'),
|
label=_('Region')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
site_group_id = DynamicModelMultipleChoiceField(
|
site_group_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=SiteGroup.objects.all(),
|
queryset=SiteGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Site group'),
|
label=_('Site group')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
site_id = DynamicModelMultipleChoiceField(
|
site_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
@ -125,8 +115,7 @@ class VirtualMachineFilterForm(LocalConfigContextFilterForm, TenancyFilterForm,
|
|||||||
'region_id': '$region_id',
|
'region_id': '$region_id',
|
||||||
'group_id': '$site_group_id',
|
'group_id': '$site_group_id',
|
||||||
},
|
},
|
||||||
label=_('Site'),
|
label=_('Site')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
role_id = DynamicModelMultipleChoiceField(
|
role_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=DeviceRole.objects.all(),
|
queryset=DeviceRole.objects.all(),
|
||||||
@ -135,8 +124,7 @@ class VirtualMachineFilterForm(LocalConfigContextFilterForm, TenancyFilterForm,
|
|||||||
query_params={
|
query_params={
|
||||||
'vm_role': "True"
|
'vm_role': "True"
|
||||||
},
|
},
|
||||||
label=_('Role'),
|
label=_('Role')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
status = forms.MultipleChoiceField(
|
status = forms.MultipleChoiceField(
|
||||||
choices=VirtualMachineStatusChoices,
|
choices=VirtualMachineStatusChoices,
|
||||||
@ -147,8 +135,7 @@ class VirtualMachineFilterForm(LocalConfigContextFilterForm, TenancyFilterForm,
|
|||||||
queryset=Platform.objects.all(),
|
queryset=Platform.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
null_option='None',
|
null_option='None',
|
||||||
label=_('Platform'),
|
label=_('Platform')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
mac_address = forms.CharField(
|
mac_address = forms.CharField(
|
||||||
required=False,
|
required=False,
|
||||||
@ -174,8 +161,7 @@ class VMInterfaceFilterForm(CustomFieldModelFilterForm):
|
|||||||
cluster_id = DynamicModelMultipleChoiceField(
|
cluster_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Cluster.objects.all(),
|
queryset=Cluster.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Cluster'),
|
label=_('Cluster')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
virtual_machine_id = DynamicModelMultipleChoiceField(
|
virtual_machine_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=VirtualMachine.objects.all(),
|
queryset=VirtualMachine.objects.all(),
|
||||||
@ -183,8 +169,7 @@ class VMInterfaceFilterForm(CustomFieldModelFilterForm):
|
|||||||
query_params={
|
query_params={
|
||||||
'cluster_id': '$cluster_id'
|
'cluster_id': '$cluster_id'
|
||||||
},
|
},
|
||||||
label=_('Virtual machine'),
|
label=_('Virtual machine')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
enabled = forms.NullBooleanField(
|
enabled = forms.NullBooleanField(
|
||||||
required=False,
|
required=False,
|
||||||
|
@ -19,8 +19,7 @@ class WirelessLANGroupFilterForm(CustomFieldModelFilterForm):
|
|||||||
parent_id = DynamicModelMultipleChoiceField(
|
parent_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=WirelessLANGroup.objects.all(),
|
queryset=WirelessLANGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Parent group'),
|
label=_('Parent group')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
@ -39,8 +38,7 @@ class WirelessLANFilterForm(CustomFieldModelFilterForm):
|
|||||||
queryset=WirelessLANGroup.objects.all(),
|
queryset=WirelessLANGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
null_option='None',
|
null_option='None',
|
||||||
label=_('Group'),
|
label=_('Group')
|
||||||
fetch_trigger='open'
|
|
||||||
)
|
)
|
||||||
auth_type = forms.ChoiceField(
|
auth_type = forms.ChoiceField(
|
||||||
required=False,
|
required=False,
|
||||||
|
@ -6,7 +6,7 @@ django-graphiql-debug-toolbar==0.2.0
|
|||||||
django-mptt==0.13.4
|
django-mptt==0.13.4
|
||||||
django-pglocks==1.0.4
|
django-pglocks==1.0.4
|
||||||
django-prometheus==2.2.0
|
django-prometheus==2.2.0
|
||||||
django-redis==5.1.0
|
django-redis==5.2.0
|
||||||
django-rq==2.5.1
|
django-rq==2.5.1
|
||||||
django-tables2==2.4.1
|
django-tables2==2.4.1
|
||||||
django-taggit==2.0.0
|
django-taggit==2.0.0
|
||||||
@ -21,7 +21,7 @@ markdown-include==0.6.0
|
|||||||
mkdocs-material==8.1.3
|
mkdocs-material==8.1.3
|
||||||
netaddr==0.8.0
|
netaddr==0.8.0
|
||||||
Pillow==8.4.0
|
Pillow==8.4.0
|
||||||
psycopg2-binary==2.9.2
|
psycopg2-binary==2.9.3
|
||||||
PyYAML==6.0
|
PyYAML==6.0
|
||||||
social-auth-app-django==5.0.0
|
social-auth-app-django==5.0.0
|
||||||
social-auth-core==4.1.0
|
social-auth-core==4.1.0
|
||||||
|
Loading…
Reference in New Issue
Block a user