mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-24 17:38:37 -06:00
Added views for editing/deleting VCMemberships
This commit is contained in:
parent
a85b3aa69f
commit
da2bff691b
@ -2219,8 +2219,12 @@ class VirtualChassisCreateForm(BootstrapMixin, forms.ModelForm):
|
|||||||
self.fields['master'].queryset = Device.objects.filter(pk__in=candidate_pks)
|
self.fields['master'].queryset = Device.objects.filter(pk__in=candidate_pks)
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# VC memberships
|
||||||
|
#
|
||||||
|
|
||||||
class VCMembershipForm(BootstrapMixin, forms.ModelForm):
|
class VCMembershipForm(BootstrapMixin, forms.ModelForm):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = VCMembership
|
model = VCMembership
|
||||||
fields = ['device', 'position', 'priority']
|
fields = ['position', 'priority']
|
||||||
|
@ -1507,7 +1507,7 @@ class VirtualChassis(models.Model):
|
|||||||
return self.master.name
|
return self.master.name
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return "{}?virtual_chassis={}".format(reverse('dcim:device_list'), self.pk)
|
return self.master.get_absolute_url()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def master(self):
|
def master(self):
|
||||||
@ -1547,13 +1547,21 @@ class VCMembership(models.Model):
|
|||||||
unique_together = ['virtual_chassis', 'position']
|
unique_together = ['virtual_chassis', 'position']
|
||||||
verbose_name = 'VC membership'
|
verbose_name = 'VC membership'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.device.name
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
|
|
||||||
|
# We have to call this here because it won't be called by VCMembershipForm
|
||||||
|
self.validate_unique()
|
||||||
|
|
||||||
# Check for master conflicts
|
# Check for master conflicts
|
||||||
if getattr(self, 'virtual_chassis', None) and self.is_master:
|
if getattr(self, 'virtual_chassis', None) and self.is_master:
|
||||||
master_conflict = VCMembership.objects.filter(virtual_chassis=self.virtual_chassis).first()
|
master_conflict = VCMembership.objects.filter(
|
||||||
|
virtual_chassis=self.virtual_chassis, is_master=True
|
||||||
|
).exclude(pk=self.pk).first()
|
||||||
if master_conflict:
|
if master_conflict:
|
||||||
raise ValidationError({
|
raise ValidationError(
|
||||||
'virtual_chassis': "{} has already been designated as the master for this virtual chassis. It must "
|
"{} has already been designated as the master for this virtual chassis. It must be demoted before "
|
||||||
"be demoted before a new master can be assigned.".format(master_conflict.device)
|
"a new master can be assigned.".format(master_conflict.device)
|
||||||
})
|
)
|
||||||
|
@ -213,4 +213,8 @@ urlpatterns = [
|
|||||||
url(r'^virtual-chassis/(?P<pk>\d+)/edit/$', views.VirtualChassisEditView.as_view(), name='virtualchassis_edit'),
|
url(r'^virtual-chassis/(?P<pk>\d+)/edit/$', views.VirtualChassisEditView.as_view(), name='virtualchassis_edit'),
|
||||||
url(r'^virtual-chassis/(?P<pk>\d+)/delete/$', views.VirtualChassisDeleteView.as_view(), name='virtualchassis_delete'),
|
url(r'^virtual-chassis/(?P<pk>\d+)/delete/$', views.VirtualChassisDeleteView.as_view(), name='virtualchassis_delete'),
|
||||||
|
|
||||||
|
# VC memberships
|
||||||
|
url(r'^vc-memberships/(?P<pk>\d+)/edit/$', views.VCMembershipEditView.as_view(), name='vcmembership_edit'),
|
||||||
|
url(r'^vc-memberships/(?P<pk>\d+)/delete/$', views.VCMembershipDeleteView.as_view(), name='vcmembership_delete'),
|
||||||
|
|
||||||
]
|
]
|
||||||
|
@ -1859,6 +1859,10 @@ class VirtualChassisCreateView(PermissionRequiredMixin, View):
|
|||||||
class _VCMembershipForm(forms.VCMembershipForm):
|
class _VCMembershipForm(forms.VCMembershipForm):
|
||||||
device = ModelChoiceField(queryset=Device.objects.filter(pk__in=device_list))
|
device = ModelChoiceField(queryset=Device.objects.filter(pk__in=device_list))
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = VCMembership
|
||||||
|
fields = ['device', 'position', 'priority']
|
||||||
|
|
||||||
VCMembershipFormSet = modelformset_factory(model=VCMembership, form=_VCMembershipForm, extra=len(device_list))
|
VCMembershipFormSet = modelformset_factory(model=VCMembership, form=_VCMembershipForm, extra=len(device_list))
|
||||||
|
|
||||||
if '_create' in request.POST:
|
if '_create' in request.POST:
|
||||||
@ -1902,3 +1906,18 @@ class VirtualChassisDeleteView(PermissionRequiredMixin, ObjectDeleteView):
|
|||||||
permission_required = 'dcim.delete_virtualchassis'
|
permission_required = 'dcim.delete_virtualchassis'
|
||||||
model = VirtualChassis
|
model = VirtualChassis
|
||||||
default_return_url = 'dcim:device_list'
|
default_return_url = 'dcim:device_list'
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# VC memberships
|
||||||
|
#
|
||||||
|
|
||||||
|
class VCMembershipEditView(PermissionRequiredMixin, ObjectEditView):
|
||||||
|
permission_required = 'dcim.change_vcmembership'
|
||||||
|
model = VCMembership
|
||||||
|
model_form = forms.VCMembershipForm
|
||||||
|
|
||||||
|
|
||||||
|
class VCMembershipDeleteView(PermissionRequiredMixin, ObjectDeleteView):
|
||||||
|
permission_required = 'dcim.delete_vcmembership'
|
||||||
|
model = VCMembership
|
||||||
|
@ -1,11 +1,44 @@
|
|||||||
{% extends 'utilities/obj_edit.html' %}
|
{% extends 'utilities/obj_edit.html' %}
|
||||||
{% load form_helpers %}
|
{% load form_helpers %}
|
||||||
|
|
||||||
{% block form %}
|
{% block content %}
|
||||||
<div class="panel panel-default">
|
{{ block.super }}
|
||||||
<div class="panel-heading"><strong>{{ obj_type|capfirst }}</strong></div>
|
<div class="row">
|
||||||
<div class="panel-body">
|
<div class="col-md-6 col-md-offset-3">
|
||||||
{% render_form form %}
|
<h3>Memberships</h3>
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<table class="table panel-body">
|
||||||
|
<tr class="table-headings">
|
||||||
|
<th>Device</th>
|
||||||
|
<th>Position</th>
|
||||||
|
<th>Master</th>
|
||||||
|
<th>Priority</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
{% for vcm in form.instance.memberships.all %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a href="{{ vcm.device.get_absolute_url }}">{{ vcm.device }}</a>
|
||||||
|
</td>
|
||||||
|
<td>{{ vcm.position }}</td>
|
||||||
|
<td>{% if vcm.is_master %}<i class="fa fa-check"></i>{% endif %}</td>
|
||||||
|
<td>{{ vcm.priority|default:"" }}</td>
|
||||||
|
<td class="text-right">
|
||||||
|
{% if perms.dcim.change_vcmembership %}
|
||||||
|
<a href="{% url 'dcim:vcmembership_edit' pk=vcm.pk %}?return_url={% url 'dcim:virtualchassis_edit' pk=vcm.virtual_chassis.pk %}" class="btn btn-warning btn-xs">
|
||||||
|
<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
{% if perms.dcim.delete_vcmembership %}
|
||||||
|
<a href="{% url 'dcim:vcmembership_delete' pk=vcm.pk %}?return_url={% url 'dcim:virtualchassis_edit' pk=vcm.virtual_chassis.pk %}" class="btn btn-danger btn-xs">
|
||||||
|
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span> Delete
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
Loading…
Reference in New Issue
Block a user