mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-26 09:16:10 -06:00
12552 get_descendants -> descendants, get_ancestors -> ancestors
This commit is contained in:
parent
da0c459e73
commit
252ca516db
@ -69,7 +69,7 @@ class Region(NestedGroupModel):
|
|||||||
def get_site_count(self):
|
def get_site_count(self):
|
||||||
return Site.objects.filter(
|
return Site.objects.filter(
|
||||||
Q(region=self) |
|
Q(region=self) |
|
||||||
Q(region__in=self.get_descendants())
|
Q(region__in=self.descendants())
|
||||||
).count()
|
).count()
|
||||||
|
|
||||||
|
|
||||||
@ -124,7 +124,7 @@ class SiteGroup(NestedGroupModel):
|
|||||||
def get_site_count(self):
|
def get_site_count(self):
|
||||||
return Site.objects.filter(
|
return Site.objects.filter(
|
||||||
Q(group=self) |
|
Q(group=self) |
|
||||||
Q(group__in=self.get_descendants())
|
Q(group__in=self.descendants())
|
||||||
).count()
|
).count()
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,8 +22,8 @@ def handle_location_site_change(instance, created, **kwargs):
|
|||||||
object instead of calling update() on the QuerySet to ensure the proper change records get created for each.
|
object instead of calling update() on the QuerySet to ensure the proper change records get created for each.
|
||||||
"""
|
"""
|
||||||
if not created:
|
if not created:
|
||||||
instance.get_descendants().update(site=instance.site)
|
instance.descendants().update(site=instance.site)
|
||||||
locations = instance.get_descendants(include_self=True).values_list('pk', flat=True)
|
locations = instance.descendants(include_self=True).values_list('pk', flat=True)
|
||||||
Rack.objects.filter(location__in=locations).update(site=instance.site)
|
Rack.objects.filter(location__in=locations).update(site=instance.site)
|
||||||
Device.objects.filter(location__in=locations).update(site=instance.site)
|
Device.objects.filter(location__in=locations).update(site=instance.site)
|
||||||
PowerPanel.objects.filter(location__in=locations).update(site=instance.site)
|
PowerPanel.objects.filter(location__in=locations).update(site=instance.site)
|
||||||
|
@ -198,7 +198,7 @@ class PathTraceView(generic.ObjectView):
|
|||||||
#
|
#
|
||||||
|
|
||||||
class RegionListView(generic.ObjectListView):
|
class RegionListView(generic.ObjectListView):
|
||||||
queryset = Region.objects.all()
|
queryset = Region.objects.all().order_siblings_by("name")
|
||||||
# queryset = Region.objects.add_related_count(
|
# queryset = Region.objects.add_related_count(
|
||||||
# Region.objects.all(),
|
# Region.objects.all(),
|
||||||
# Site,
|
# Site,
|
||||||
@ -216,7 +216,7 @@ class RegionView(generic.ObjectView):
|
|||||||
queryset = Region.objects.all()
|
queryset = Region.objects.all()
|
||||||
|
|
||||||
def get_extra_context(self, request, instance):
|
def get_extra_context(self, request, instance):
|
||||||
regions = instance.get_descendants(include_self=True)
|
regions = instance.descendants(include_self=True)
|
||||||
related_models = (
|
related_models = (
|
||||||
(Site.objects.restrict(request.user, 'view').filter(region__in=regions), 'region_id'),
|
(Site.objects.restrict(request.user, 'view').filter(region__in=regions), 'region_id'),
|
||||||
(Location.objects.restrict(request.user, 'view').filter(site__region__in=regions), 'region_id'),
|
(Location.objects.restrict(request.user, 'view').filter(site__region__in=regions), 'region_id'),
|
||||||
@ -299,7 +299,7 @@ class SiteGroupView(generic.ObjectView):
|
|||||||
queryset = SiteGroup.objects.all()
|
queryset = SiteGroup.objects.all()
|
||||||
|
|
||||||
def get_extra_context(self, request, instance):
|
def get_extra_context(self, request, instance):
|
||||||
groups = instance.get_descendants(include_self=True)
|
groups = instance.descendants(include_self=True)
|
||||||
related_models = (
|
related_models = (
|
||||||
(Site.objects.restrict(request.user, 'view').filter(group__in=groups), 'group_id'),
|
(Site.objects.restrict(request.user, 'view').filter(group__in=groups), 'group_id'),
|
||||||
(Location.objects.restrict(request.user, 'view').filter(site__group__in=groups), 'site_group_id'),
|
(Location.objects.restrict(request.user, 'view').filter(site__group__in=groups), 'site_group_id'),
|
||||||
@ -487,7 +487,7 @@ class LocationView(generic.ObjectView):
|
|||||||
queryset = Location.objects.all()
|
queryset = Location.objects.all()
|
||||||
|
|
||||||
def get_extra_context(self, request, instance):
|
def get_extra_context(self, request, instance):
|
||||||
locations = instance.get_descendants(include_self=True)
|
locations = instance.descendants(include_self=True)
|
||||||
related_models = (
|
related_models = (
|
||||||
(Rack.objects.restrict(request.user, 'view').filter(location__in=locations), 'location_id'),
|
(Rack.objects.restrict(request.user, 'view').filter(location__in=locations), 'location_id'),
|
||||||
(Device.objects.restrict(request.user, 'view').filter(location__in=locations), 'location_id'),
|
(Device.objects.restrict(request.user, 'view').filter(location__in=locations), 'location_id'),
|
||||||
|
@ -33,11 +33,11 @@ class ConfigContextQuerySet(RestrictedQuerySet):
|
|||||||
|
|
||||||
# Match against the directly assigned region as well as any parent regions.
|
# Match against the directly assigned region as well as any parent regions.
|
||||||
region = getattr(obj.site, 'region', None)
|
region = getattr(obj.site, 'region', None)
|
||||||
regions = region.get_ancestors(include_self=True) if region else []
|
regions = region.ancestors(include_self=True) if region else []
|
||||||
|
|
||||||
# Match against the directly assigned site group as well as any parent site groups.
|
# Match against the directly assigned site group as well as any parent site groups.
|
||||||
sitegroup = getattr(obj.site, 'group', None)
|
sitegroup = getattr(obj.site, 'group', None)
|
||||||
sitegroups = sitegroup.get_ancestors(include_self=True) if sitegroup else []
|
sitegroups = sitegroup.ancestors(include_self=True) if sitegroup else []
|
||||||
|
|
||||||
queryset = self.filter(
|
queryset = self.filter(
|
||||||
Q(regions__in=regions) | Q(regions=None),
|
Q(regions__in=regions) | Q(regions=None),
|
||||||
|
@ -43,12 +43,12 @@ class VLANQuerySet(RestrictedQuerySet):
|
|||||||
if device.site.region:
|
if device.site.region:
|
||||||
q |= Q(
|
q |= Q(
|
||||||
scope_type=ContentType.objects.get_by_natural_key('dcim', 'region'),
|
scope_type=ContentType.objects.get_by_natural_key('dcim', 'region'),
|
||||||
scope_id__in=device.site.region.get_ancestors(include_self=True)
|
scope_id__in=device.site.region.ancestors(include_self=True)
|
||||||
)
|
)
|
||||||
if device.site.group:
|
if device.site.group:
|
||||||
q |= Q(
|
q |= Q(
|
||||||
scope_type=ContentType.objects.get_by_natural_key('dcim', 'sitegroup'),
|
scope_type=ContentType.objects.get_by_natural_key('dcim', 'sitegroup'),
|
||||||
scope_id__in=device.site.group.get_ancestors(include_self=True)
|
scope_id__in=device.site.group.ancestors(include_self=True)
|
||||||
)
|
)
|
||||||
q |= Q(
|
q |= Q(
|
||||||
scope_type=ContentType.objects.get_by_natural_key('dcim', 'site'),
|
scope_type=ContentType.objects.get_by_natural_key('dcim', 'site'),
|
||||||
@ -57,7 +57,7 @@ class VLANQuerySet(RestrictedQuerySet):
|
|||||||
if device.location:
|
if device.location:
|
||||||
q |= Q(
|
q |= Q(
|
||||||
scope_type=ContentType.objects.get_by_natural_key('dcim', 'location'),
|
scope_type=ContentType.objects.get_by_natural_key('dcim', 'location'),
|
||||||
scope_id__in=device.location.get_ancestors(include_self=True)
|
scope_id__in=device.location.ancestors(include_self=True)
|
||||||
)
|
)
|
||||||
if device.rack:
|
if device.rack:
|
||||||
q |= Q(
|
q |= Q(
|
||||||
@ -102,12 +102,12 @@ class VLANQuerySet(RestrictedQuerySet):
|
|||||||
if site.region:
|
if site.region:
|
||||||
q |= Q(
|
q |= Q(
|
||||||
scope_type=ContentType.objects.get_by_natural_key('dcim', 'region'),
|
scope_type=ContentType.objects.get_by_natural_key('dcim', 'region'),
|
||||||
scope_id__in=site.region.get_ancestors(include_self=True)
|
scope_id__in=site.region.ancestors(include_self=True)
|
||||||
)
|
)
|
||||||
if site.group:
|
if site.group:
|
||||||
q |= Q(
|
q |= Q(
|
||||||
scope_type=ContentType.objects.get_by_natural_key('dcim', 'sitegroup'),
|
scope_type=ContentType.objects.get_by_natural_key('dcim', 'sitegroup'),
|
||||||
scope_id__in=site.group.get_ancestors(include_self=True)
|
scope_id__in=site.group.ancestors(include_self=True)
|
||||||
)
|
)
|
||||||
vlan_groups = VLANGroup.objects.filter(q)
|
vlan_groups = VLANGroup.objects.filter(q)
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ class PrimaryModel(NetBoxModel):
|
|||||||
class NestedGroupModel(CloningMixin, NetBoxFeatureSet, TreeNode):
|
class NestedGroupModel(CloningMixin, NetBoxFeatureSet, TreeNode):
|
||||||
"""
|
"""
|
||||||
Base model for objects which are used to form a hierarchy (regions, locations, etc.). These models nest
|
Base model for objects which are used to form a hierarchy (regions, locations, etc.). These models nest
|
||||||
recursively using MPTT. Within each parent, each child instance must have a unique name.
|
recursively using tree-queries. Within each parent, each child instance must have a unique name.
|
||||||
"""
|
"""
|
||||||
name = models.CharField(
|
name = models.CharField(
|
||||||
max_length=100
|
max_length=100
|
||||||
@ -128,15 +128,6 @@ class NestedGroupModel(CloningMixin, NetBoxFeatureSet, TreeNode):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
def clean(self):
|
|
||||||
super().clean()
|
|
||||||
|
|
||||||
# An MPTT model cannot be its own parent
|
|
||||||
if self.pk and self.parent and self.parent in self.get_descendants(include_self=True):
|
|
||||||
raise ValidationError({
|
|
||||||
"parent": f"Cannot assign self or child {self._meta.verbose_name} as parent."
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
class OrganizationalModel(NetBoxFeatureSet, models.Model):
|
class OrganizationalModel(NetBoxFeatureSet, models.Model):
|
||||||
"""
|
"""
|
||||||
|
@ -538,7 +538,7 @@ class MPTTColumn(tables.TemplateColumn):
|
|||||||
template_code = """
|
template_code = """
|
||||||
{% load helpers %}
|
{% load helpers %}
|
||||||
{% if not table.order_by %}
|
{% if not table.order_by %}
|
||||||
{% for i in record.level|as_range %}<i class="mdi mdi-circle-small"></i>{% endfor %}
|
{% for i in record.tree_depth|as_range %}<i class="mdi mdi-circle-small"></i>{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a href="{{ record.get_absolute_url }}">{{ record.name }}</a>
|
<a href="{{ record.get_absolute_url }}">{{ record.name }}</a>
|
||||||
"""
|
"""
|
||||||
|
@ -60,7 +60,7 @@ class TenantGroupView(generic.ObjectView):
|
|||||||
queryset = TenantGroup.objects.all()
|
queryset = TenantGroup.objects.all()
|
||||||
|
|
||||||
def get_extra_context(self, request, instance):
|
def get_extra_context(self, request, instance):
|
||||||
groups = instance.get_descendants(include_self=True)
|
groups = instance.descendants(include_self=True)
|
||||||
related_models = (
|
related_models = (
|
||||||
(Tenant.objects.restrict(request.user, 'view').filter(group__in=groups), 'group_id'),
|
(Tenant.objects.restrict(request.user, 'view').filter(group__in=groups), 'group_id'),
|
||||||
)
|
)
|
||||||
@ -219,7 +219,7 @@ class ContactGroupView(generic.ObjectView):
|
|||||||
queryset = ContactGroup.objects.all()
|
queryset = ContactGroup.objects.all()
|
||||||
|
|
||||||
def get_extra_context(self, request, instance):
|
def get_extra_context(self, request, instance):
|
||||||
groups = instance.get_descendants(include_self=True)
|
groups = instance.descendants(include_self=True)
|
||||||
related_models = (
|
related_models = (
|
||||||
(Contact.objects.restrict(request.user, 'view').filter(group__in=groups), 'group_id'),
|
(Contact.objects.restrict(request.user, 'view').filter(group__in=groups), 'group_id'),
|
||||||
)
|
)
|
||||||
|
@ -116,7 +116,7 @@ class TreeNodeMultipleChoiceFilter(django_filters.ModelMultipleChoiceFilter):
|
|||||||
return super().get_filter_predicate(v)
|
return super().get_filter_predicate(v)
|
||||||
|
|
||||||
def filter(self, qs, value):
|
def filter(self, qs, value):
|
||||||
value = [node.get_descendants(include_self=True) if not isinstance(node, str) else node for node in value]
|
value = [node.descendants(include_self=True) if not isinstance(node, str) else node for node in value]
|
||||||
return super().filter(qs, value)
|
return super().filter(qs, value)
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ class WirelessLANGroupView(generic.ObjectView):
|
|||||||
queryset = WirelessLANGroup.objects.all()
|
queryset = WirelessLANGroup.objects.all()
|
||||||
|
|
||||||
def get_extra_context(self, request, instance):
|
def get_extra_context(self, request, instance):
|
||||||
groups = instance.get_descendants(include_self=True)
|
groups = instance.descendants(include_self=True)
|
||||||
related_models = (
|
related_models = (
|
||||||
(WirelessLAN.objects.restrict(request.user, 'view').filter(group__in=groups), 'group_id'),
|
(WirelessLAN.objects.restrict(request.user, 'view').filter(group__in=groups), 'group_id'),
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user