mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Merge branch 'feature' of https://github.com/netbox-community/netbox into feature
# Conflicts: # netbox/project-static/js/forms.js # netbox/templates/dcim/location.html # netbox/templates/generic/object_list.html
This commit is contained in:
@ -209,6 +209,14 @@ class LocationFilterSet(BaseFilterSet, NameSlugSearchFilterSet):
|
||||
model = Location
|
||||
fields = ['id', 'name', 'slug', 'description']
|
||||
|
||||
def search(self, queryset, name, value):
|
||||
if not value.strip():
|
||||
return queryset
|
||||
return queryset.filter(
|
||||
Q(name__icontains=value) |
|
||||
Q(description__icontains=value)
|
||||
)
|
||||
|
||||
|
||||
class RackRoleFilterSet(BaseFilterSet, NameSlugSearchFilterSet):
|
||||
|
||||
|
@ -230,7 +230,7 @@ class RegionBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
|
||||
nullable_fields = ['parent', 'description']
|
||||
|
||||
|
||||
class RegionFilterForm(BootstrapMixin, forms.Form):
|
||||
class RegionFilterForm(BootstrapMixin, CustomFieldFilterForm):
|
||||
model = Site
|
||||
q = forms.CharField(
|
||||
required=False,
|
||||
@ -287,8 +287,8 @@ class SiteGroupBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
|
||||
nullable_fields = ['parent', 'description']
|
||||
|
||||
|
||||
class SiteGroupFilterForm(BootstrapMixin, forms.Form):
|
||||
model = Site
|
||||
class SiteGroupFilterForm(BootstrapMixin, CustomFieldFilterForm):
|
||||
model = SiteGroup
|
||||
q = forms.CharField(
|
||||
required=False,
|
||||
label=_('Search')
|
||||
@ -557,7 +557,12 @@ class LocationBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
|
||||
nullable_fields = ['parent', 'description']
|
||||
|
||||
|
||||
class LocationFilterForm(BootstrapMixin, forms.Form):
|
||||
class LocationFilterForm(BootstrapMixin, CustomFieldFilterForm):
|
||||
model = Location
|
||||
q = forms.CharField(
|
||||
required=False,
|
||||
label=_('Search')
|
||||
)
|
||||
region_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Region.objects.all(),
|
||||
required=False,
|
||||
@ -2424,10 +2429,11 @@ class DeviceFilterForm(BootstrapMixin, LocalConfigContextFilterForm, TenancyFilt
|
||||
location_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Location.objects.all(),
|
||||
required=False,
|
||||
label=_('Location'),
|
||||
null_option='None',
|
||||
query_params={
|
||||
'site_id': '$site_id'
|
||||
}
|
||||
},
|
||||
label=_('Location')
|
||||
)
|
||||
rack_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Rack.objects.all(),
|
||||
|
@ -291,6 +291,7 @@ class ConsolePortTable(DeviceComponentTable, PathEndpointTable):
|
||||
class DeviceConsolePortTable(ConsolePortTable):
|
||||
name = tables.TemplateColumn(
|
||||
template_code='<i class="mdi mdi-console"></i> <a href="{{ record.get_absolute_url }}">{{ value }}</a>',
|
||||
order_by=Accessor('_name'),
|
||||
attrs={'td': {'class': 'text-nowrap'}}
|
||||
)
|
||||
actions = ButtonsColumn(
|
||||
@ -335,6 +336,7 @@ class DeviceConsoleServerPortTable(ConsoleServerPortTable):
|
||||
name = tables.TemplateColumn(
|
||||
template_code='<i class="mdi mdi-console-network-outline"></i> '
|
||||
'<a href="{{ record.get_absolute_url }}">{{ value }}</a>',
|
||||
order_by=Accessor('_name'),
|
||||
attrs={'td': {'class': 'text-nowrap'}}
|
||||
)
|
||||
actions = ButtonsColumn(
|
||||
@ -379,6 +381,7 @@ class DevicePowerPortTable(PowerPortTable):
|
||||
name = tables.TemplateColumn(
|
||||
template_code='<i class="mdi mdi-power-plug-outline"></i> <a href="{{ record.get_absolute_url }}">'
|
||||
'{{ value }}</a>',
|
||||
order_by=Accessor('_name'),
|
||||
attrs={'td': {'class': 'text-nowrap'}}
|
||||
)
|
||||
actions = ButtonsColumn(
|
||||
@ -428,6 +431,7 @@ class PowerOutletTable(DeviceComponentTable, PathEndpointTable):
|
||||
class DevicePowerOutletTable(PowerOutletTable):
|
||||
name = tables.TemplateColumn(
|
||||
template_code='<i class="mdi mdi-power-socket"></i> <a href="{{ record.get_absolute_url }}">{{ value }}</a>',
|
||||
order_by=Accessor('_name'),
|
||||
attrs={'td': {'class': 'text-nowrap'}}
|
||||
)
|
||||
actions = ButtonsColumn(
|
||||
@ -492,6 +496,7 @@ class DeviceInterfaceTable(InterfaceTable):
|
||||
template_code='<i class="mdi mdi-{% if iface.mgmt_only %}wrench{% elif iface.is_lag %}drag-horizontal-variant'
|
||||
'{% elif iface.is_virtual %}circle{% elif iface.is_wireless %}wifi{% else %}ethernet'
|
||||
'{% endif %}"></i> <a href="{{ record.get_absolute_url }}">{{ value }}</a>',
|
||||
order_by=Accessor('_name'),
|
||||
attrs={'td': {'class': 'text-nowrap'}}
|
||||
)
|
||||
parent = tables.Column(
|
||||
@ -555,6 +560,7 @@ class DeviceFrontPortTable(FrontPortTable):
|
||||
name = tables.TemplateColumn(
|
||||
template_code='<i class="mdi mdi-square-rounded{% if not record.cable %}-outline{% endif %}"></i> '
|
||||
'<a href="{{ record.get_absolute_url }}">{{ value }}</a>',
|
||||
order_by=Accessor('_name'),
|
||||
attrs={'td': {'class': 'text-nowrap'}}
|
||||
)
|
||||
actions = ButtonsColumn(
|
||||
@ -602,6 +608,7 @@ class DeviceRearPortTable(RearPortTable):
|
||||
name = tables.TemplateColumn(
|
||||
template_code='<i class="mdi mdi-square-rounded{% if not record.cable %}-outline{% endif %}"></i> '
|
||||
'<a href="{{ record.get_absolute_url }}">{{ value }}</a>',
|
||||
order_by=Accessor('_name'),
|
||||
attrs={'td': {'class': 'text-nowrap'}}
|
||||
)
|
||||
actions = ButtonsColumn(
|
||||
@ -651,6 +658,7 @@ class DeviceDeviceBayTable(DeviceBayTable):
|
||||
name = tables.TemplateColumn(
|
||||
template_code='<i class="mdi mdi-circle{% if record.installed_device %}slice-8{% else %}outline{% endif %}'
|
||||
'"></i> <a href="{{ record.get_absolute_url }}">{{ value }}</a>',
|
||||
order_by=Accessor('_name'),
|
||||
attrs={'td': {'class': 'text-nowrap'}}
|
||||
)
|
||||
actions = ButtonsColumn(
|
||||
@ -698,6 +706,7 @@ class DeviceInventoryItemTable(InventoryItemTable):
|
||||
name = tables.TemplateColumn(
|
||||
template_code='<a href="{{ record.get_absolute_url }}" style="padding-left: {{ record.level }}0px">'
|
||||
'{{ value }}</a>',
|
||||
order_by=Accessor('_name'),
|
||||
attrs={'td': {'class': 'text-nowrap'}}
|
||||
)
|
||||
actions = ButtonsColumn(
|
||||
|
@ -364,16 +364,30 @@ class LocationView(generic.ObjectView):
|
||||
queryset = Location.objects.all()
|
||||
|
||||
def get_extra_context(self, request, instance):
|
||||
devices = Device.objects.restrict(request.user, 'view').filter(
|
||||
location=instance
|
||||
)
|
||||
location_ids = instance.get_descendants(include_self=True).values_list('pk', flat=True)
|
||||
rack_count = Rack.objects.filter(location__in=location_ids).count()
|
||||
device_count = Device.objects.filter(location__in=location_ids).count()
|
||||
|
||||
devices_table = tables.DeviceTable(devices)
|
||||
devices_table.columns.hide('location')
|
||||
paginate_table(devices_table, request)
|
||||
child_locations = Location.objects.add_related_count(
|
||||
Location.objects.add_related_count(
|
||||
Location.objects.all(),
|
||||
Device,
|
||||
'location',
|
||||
'device_count',
|
||||
cumulative=True
|
||||
),
|
||||
Rack,
|
||||
'location',
|
||||
'rack_count',
|
||||
cumulative=True
|
||||
).filter(pk__in=location_ids).exclude(pk=instance.pk)
|
||||
child_locations_table = tables.LocationTable(child_locations)
|
||||
paginate_table(child_locations_table, request)
|
||||
|
||||
return {
|
||||
'devices_table': devices_table,
|
||||
'rack_count': rack_count,
|
||||
'device_count': device_count,
|
||||
'child_locations_table': child_locations_table,
|
||||
}
|
||||
|
||||
|
||||
@ -1305,8 +1319,7 @@ class DeviceConsolePortsView(generic.ObjectView):
|
||||
)
|
||||
consoleport_table = tables.DeviceConsolePortTable(
|
||||
data=consoleports,
|
||||
user=request.user,
|
||||
orderable=False
|
||||
user=request.user
|
||||
)
|
||||
if request.user.has_perm('dcim.change_consoleport') or request.user.has_perm('dcim.delete_consoleport'):
|
||||
consoleport_table.columns.show('pk')
|
||||
@ -1330,8 +1343,7 @@ class DeviceConsoleServerPortsView(generic.ObjectView):
|
||||
)
|
||||
consoleserverport_table = tables.DeviceConsoleServerPortTable(
|
||||
data=consoleserverports,
|
||||
user=request.user,
|
||||
orderable=False
|
||||
user=request.user
|
||||
)
|
||||
if request.user.has_perm('dcim.change_consoleserverport') or \
|
||||
request.user.has_perm('dcim.delete_consoleserverport'):
|
||||
@ -1354,8 +1366,7 @@ class DevicePowerPortsView(generic.ObjectView):
|
||||
)
|
||||
powerport_table = tables.DevicePowerPortTable(
|
||||
data=powerports,
|
||||
user=request.user,
|
||||
orderable=False
|
||||
user=request.user
|
||||
)
|
||||
if request.user.has_perm('dcim.change_powerport') or request.user.has_perm('dcim.delete_powerport'):
|
||||
powerport_table.columns.show('pk')
|
||||
@ -1377,8 +1388,7 @@ class DevicePowerOutletsView(generic.ObjectView):
|
||||
)
|
||||
poweroutlet_table = tables.DevicePowerOutletTable(
|
||||
data=poweroutlets,
|
||||
user=request.user,
|
||||
orderable=False
|
||||
user=request.user
|
||||
)
|
||||
if request.user.has_perm('dcim.change_poweroutlet') or request.user.has_perm('dcim.delete_poweroutlet'):
|
||||
poweroutlet_table.columns.show('pk')
|
||||
@ -1402,8 +1412,7 @@ class DeviceInterfacesView(generic.ObjectView):
|
||||
)
|
||||
interface_table = tables.DeviceInterfaceTable(
|
||||
data=interfaces,
|
||||
user=request.user,
|
||||
orderable=False
|
||||
user=request.user
|
||||
)
|
||||
if request.user.has_perm('dcim.change_interface') or request.user.has_perm('dcim.delete_interface'):
|
||||
interface_table.columns.show('pk')
|
||||
@ -1425,8 +1434,7 @@ class DeviceFrontPortsView(generic.ObjectView):
|
||||
)
|
||||
frontport_table = tables.DeviceFrontPortTable(
|
||||
data=frontports,
|
||||
user=request.user,
|
||||
orderable=False
|
||||
user=request.user
|
||||
)
|
||||
if request.user.has_perm('dcim.change_frontport') or request.user.has_perm('dcim.delete_frontport'):
|
||||
frontport_table.columns.show('pk')
|
||||
@ -1446,8 +1454,7 @@ class DeviceRearPortsView(generic.ObjectView):
|
||||
rearports = RearPort.objects.restrict(request.user, 'view').filter(device=instance).prefetch_related('cable')
|
||||
rearport_table = tables.DeviceRearPortTable(
|
||||
data=rearports,
|
||||
user=request.user,
|
||||
orderable=False
|
||||
user=request.user
|
||||
)
|
||||
if request.user.has_perm('dcim.change_rearport') or request.user.has_perm('dcim.delete_rearport'):
|
||||
rearport_table.columns.show('pk')
|
||||
@ -1469,8 +1476,7 @@ class DeviceDeviceBaysView(generic.ObjectView):
|
||||
)
|
||||
devicebay_table = tables.DeviceDeviceBayTable(
|
||||
data=devicebays,
|
||||
user=request.user,
|
||||
orderable=False
|
||||
user=request.user
|
||||
)
|
||||
if request.user.has_perm('dcim.change_devicebay') or request.user.has_perm('dcim.delete_devicebay'):
|
||||
devicebay_table.columns.show('pk')
|
||||
@ -1492,8 +1498,7 @@ class DeviceInventoryView(generic.ObjectView):
|
||||
).prefetch_related('manufacturer')
|
||||
inventoryitem_table = tables.DeviceInventoryItemTable(
|
||||
data=inventoryitems,
|
||||
user=request.user,
|
||||
orderable=False
|
||||
user=request.user
|
||||
)
|
||||
if request.user.has_perm('dcim.change_inventoryitem') or request.user.has_perm('dcim.delete_inventoryitem'):
|
||||
inventoryitem_table.columns.show('pk')
|
||||
|
Reference in New Issue
Block a user