mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-14 01:41:22 -06:00
* Fixes: #13918 - Add facilities field to Location model. * Stupidly forgot to `git add` * Fix errant reference to site. * Misc cleanup --------- Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
This commit is contained in:
parent
78bd7dec48
commit
19f577ccaf
@ -26,3 +26,7 @@ The location's operational status.
|
|||||||
|
|
||||||
!!! tip
|
!!! tip
|
||||||
Additional statuses may be defined by setting `Location.status` under the [`FIELD_CHOICES`](../../configuration/data-validation.md#field_choices) configuration parameter.
|
Additional statuses may be defined by setting `Location.status` under the [`FIELD_CHOICES`](../../configuration/data-validation.md#field_choices) configuration parameter.
|
||||||
|
|
||||||
|
### Facility
|
||||||
|
|
||||||
|
Data center or facility designation for identifying the location.
|
||||||
|
@ -92,7 +92,7 @@ class LocationSerializer(NestedGroupModelSerializer):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = Location
|
model = Location
|
||||||
fields = [
|
fields = [
|
||||||
'id', 'url', 'display', 'name', 'slug', 'site', 'parent', 'status', 'tenant', 'description', 'tags',
|
'id', 'url', 'display', 'name', 'slug', 'site', 'parent', 'status', 'tenant', 'facility', 'description',
|
||||||
'custom_fields', 'created', 'last_updated', 'rack_count', 'device_count', '_depth',
|
'tags', 'custom_fields', 'created', 'last_updated', 'rack_count', 'device_count', '_depth',
|
||||||
]
|
]
|
||||||
brief_fields = ('id', 'url', 'display', 'name', 'slug', 'description', 'rack_count', '_depth')
|
brief_fields = ('id', 'url', 'display', 'name', 'slug', 'description', 'rack_count', '_depth')
|
||||||
|
@ -270,13 +270,14 @@ class LocationFilterSet(TenancyFilterSet, ContactModelFilterSet, OrganizationalM
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Location
|
model = Location
|
||||||
fields = ('id', 'name', 'slug', 'status', 'description')
|
fields = ('id', 'name', 'slug', 'status', 'facility', 'description')
|
||||||
|
|
||||||
def search(self, queryset, name, value):
|
def search(self, queryset, name, value):
|
||||||
if not value.strip():
|
if not value.strip():
|
||||||
return queryset
|
return queryset
|
||||||
return queryset.filter(
|
return queryset.filter(
|
||||||
Q(name__icontains=value) |
|
Q(name__icontains=value) |
|
||||||
|
Q(facility__icontains=value) |
|
||||||
Q(description__icontains=value)
|
Q(description__icontains=value)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -157,7 +157,7 @@ class LocationImportForm(NetBoxModelImportForm):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Location
|
model = Location
|
||||||
fields = ('site', 'parent', 'name', 'slug', 'status', 'tenant', 'description', 'tags')
|
fields = ('site', 'parent', 'name', 'slug', 'status', 'tenant', 'facility', 'description', 'tags')
|
||||||
|
|
||||||
def __init__(self, data=None, *args, **kwargs):
|
def __init__(self, data=None, *args, **kwargs):
|
||||||
super().__init__(data, *args, **kwargs)
|
super().__init__(data, *args, **kwargs)
|
||||||
|
@ -179,14 +179,14 @@ class LocationForm(TenancyForm, NetBoxModelForm):
|
|||||||
slug = SlugField()
|
slug = SlugField()
|
||||||
|
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
(_('Location'), ('site', 'parent', 'name', 'slug', 'status', 'description', 'tags')),
|
(_('Location'), ('site', 'parent', 'name', 'slug', 'status', 'facility', 'description', 'tags')),
|
||||||
(_('Tenancy'), ('tenant_group', 'tenant')),
|
(_('Tenancy'), ('tenant_group', 'tenant')),
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Location
|
model = Location
|
||||||
fields = (
|
fields = (
|
||||||
'site', 'parent', 'name', 'slug', 'status', 'description', 'tenant_group', 'tenant', 'tags',
|
'site', 'parent', 'name', 'slug', 'status', 'description', 'tenant_group', 'tenant', 'facility', 'tags',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
18
netbox/dcim/migrations/0186_location_facility.py
Normal file
18
netbox/dcim/migrations/0186_location_facility.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 4.2.4 on 2024-03-17 02:21
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('dcim', '0185_gfk_indexes'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='location',
|
||||||
|
name='facility',
|
||||||
|
field=models.CharField(blank=True, max_length=50),
|
||||||
|
),
|
||||||
|
]
|
@ -275,6 +275,12 @@ class Location(ContactsMixin, ImageAttachmentsMixin, NestedGroupModel):
|
|||||||
blank=True,
|
blank=True,
|
||||||
null=True
|
null=True
|
||||||
)
|
)
|
||||||
|
facility = models.CharField(
|
||||||
|
verbose_name=_('facility'),
|
||||||
|
max_length=50,
|
||||||
|
blank=True,
|
||||||
|
help_text=_('Local facility ID or description')
|
||||||
|
)
|
||||||
|
|
||||||
# Generic relations
|
# Generic relations
|
||||||
vlan_groups = GenericRelation(
|
vlan_groups = GenericRelation(
|
||||||
@ -284,7 +290,7 @@ class Location(ContactsMixin, ImageAttachmentsMixin, NestedGroupModel):
|
|||||||
related_query_name='location'
|
related_query_name='location'
|
||||||
)
|
)
|
||||||
|
|
||||||
clone_fields = ('site', 'parent', 'status', 'tenant', 'description')
|
clone_fields = ('site', 'parent', 'status', 'tenant', 'facility', 'description')
|
||||||
prerequisite_models = (
|
prerequisite_models = (
|
||||||
'dcim.Site',
|
'dcim.Site',
|
||||||
)
|
)
|
||||||
|
@ -132,10 +132,11 @@ class LocationIndex(SearchIndex):
|
|||||||
model = models.Location
|
model = models.Location
|
||||||
fields = (
|
fields = (
|
||||||
('name', 100),
|
('name', 100),
|
||||||
|
('facility', 100),
|
||||||
('slug', 110),
|
('slug', 110),
|
||||||
('description', 500),
|
('description', 500),
|
||||||
)
|
)
|
||||||
display_attrs = ('site', 'status', 'tenant', 'description')
|
display_attrs = ('site', 'status', 'tenant', 'facility', 'description')
|
||||||
|
|
||||||
|
|
||||||
@register_search
|
@register_search
|
||||||
|
@ -152,7 +152,9 @@ class LocationTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
|
|||||||
class Meta(NetBoxTable.Meta):
|
class Meta(NetBoxTable.Meta):
|
||||||
model = Location
|
model = Location
|
||||||
fields = (
|
fields = (
|
||||||
'pk', 'id', 'name', 'site', 'status', 'tenant', 'tenant_group', 'rack_count', 'device_count', 'description',
|
'pk', 'id', 'name', 'site', 'status', 'facility', 'tenant', 'tenant_group', 'rack_count', 'device_count',
|
||||||
'slug', 'contacts', 'tags', 'actions', 'created', 'last_updated',
|
'description', 'slug', 'contacts', 'tags', 'actions', 'created', 'last_updated',
|
||||||
|
)
|
||||||
|
default_columns = (
|
||||||
|
'pk', 'name', 'site', 'status', 'facility', 'tenant', 'rack_count', 'device_count', 'description'
|
||||||
)
|
)
|
||||||
default_columns = ('pk', 'name', 'site', 'status', 'tenant', 'rack_count', 'device_count', 'description')
|
|
||||||
|
@ -359,9 +359,9 @@ class LocationTestCase(TestCase, ChangeLoggedFilterSetTests):
|
|||||||
location.save()
|
location.save()
|
||||||
|
|
||||||
locations = (
|
locations = (
|
||||||
Location(name='Location 1A', slug='location-1a', site=sites[0], parent=parent_locations[0], status=LocationStatusChoices.STATUS_PLANNED, description='foobar1'),
|
Location(name='Location 1A', slug='location-1a', site=sites[0], parent=parent_locations[0], status=LocationStatusChoices.STATUS_PLANNED, facility='Facility 1', description='foobar1'),
|
||||||
Location(name='Location 2A', slug='location-2a', site=sites[1], parent=parent_locations[1], status=LocationStatusChoices.STATUS_STAGING, description='foobar2'),
|
Location(name='Location 2A', slug='location-2a', site=sites[1], parent=parent_locations[1], status=LocationStatusChoices.STATUS_STAGING, facility='Facility 2', description='foobar2'),
|
||||||
Location(name='Location 3A', slug='location-3a', site=sites[2], parent=parent_locations[2], status=LocationStatusChoices.STATUS_DECOMMISSIONING, description='foobar3'),
|
Location(name='Location 3A', slug='location-3a', site=sites[2], parent=parent_locations[2], status=LocationStatusChoices.STATUS_DECOMMISSIONING, facility='Facility 3', description='foobar3'),
|
||||||
)
|
)
|
||||||
for location in locations:
|
for location in locations:
|
||||||
location.save()
|
location.save()
|
||||||
@ -390,6 +390,10 @@ class LocationTestCase(TestCase, ChangeLoggedFilterSetTests):
|
|||||||
params = {'status': [LocationStatusChoices.STATUS_PLANNED, LocationStatusChoices.STATUS_STAGING]}
|
params = {'status': [LocationStatusChoices.STATUS_PLANNED, LocationStatusChoices.STATUS_STAGING]}
|
||||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
||||||
|
|
||||||
|
def test_facility(self):
|
||||||
|
params = {'facility': ['Facility 1', 'Facility 2']}
|
||||||
|
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
||||||
|
|
||||||
def test_description(self):
|
def test_description(self):
|
||||||
params = {'description': ['foobar1', 'foobar2']}
|
params = {'description': ['foobar1', 'foobar2']}
|
||||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
||||||
|
@ -213,6 +213,7 @@ class LocationTestCase(ViewTestCases.OrganizationalObjectViewTestCase):
|
|||||||
'slug': 'location-x',
|
'slug': 'location-x',
|
||||||
'site': site.pk,
|
'site': site.pk,
|
||||||
'status': LocationStatusChoices.STATUS_PLANNED,
|
'status': LocationStatusChoices.STATUS_PLANNED,
|
||||||
|
'facility': 'Facility X',
|
||||||
'tenant': tenant.pk,
|
'tenant': tenant.pk,
|
||||||
'description': 'A new location',
|
'description': 'A new location',
|
||||||
'tags': [t.pk for t in tags],
|
'tags': [t.pk for t in tags],
|
||||||
|
@ -54,6 +54,10 @@
|
|||||||
{{ object.tenant|linkify|placeholder }}
|
{{ object.tenant|linkify|placeholder }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">{% trans "Facility" %}</th>
|
||||||
|
<td>{{ object.facility|placeholder }}</td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
{% include 'inc/panels/tags.html' %}
|
{% include 'inc/panels/tags.html' %}
|
||||||
|
Loading…
Reference in New Issue
Block a user