1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

#2434: Refactor ComponentCreateView to use generic form validation method

New validate_form method on ComponentCreateView handles validation generically, which any post() method on ComponentCreateView can use to validate the form but handle the response differently as needed.
This commit is contained in:
checktheroads
2021-05-08 12:01:25 -07:00
parent 515aed7022
commit 2d2719cfb2
2 changed files with 38 additions and 72 deletions

View File

@@ -1914,65 +1914,22 @@ class InterfaceCreateView(generic.ComponentCreateView):
template_name = 'dcim/device_component_add.html'
def post(self, request):
"""
Override inherited post() method to handle request to assign newly created
interface objects (first object) to an IP Address object.
"""
logger = logging.getLogger('netbox.dcim.views.InterfaceCreateView')
form = self.form(request.POST, initial=request.GET)
self.validate_form(request, form)
if form.is_valid():
new_components = []
data = deepcopy(request.POST)
names = form.cleaned_data['name_pattern']
labels = form.cleaned_data.get('label_pattern')
for i, name in enumerate(names):
label = labels[i] if labels else None
# Initialize the individual component form
data['name'] = name
data['label'] = label
if hasattr(form, 'get_iterative_data'):
data.update(form.get_iterative_data(i))
component_form = self.model_form(data)
if component_form.is_valid():
new_components.append(component_form)
else:
for field, errors in component_form.errors.as_data().items():
# Assign errors on the child form's name/label field to name_pattern/label_pattern on the parent form
if field == 'name':
field = 'name_pattern'
elif field == 'label':
field = 'label_pattern'
for e in errors:
form.add_error(field, '{}: {}'.format(name, ', '.join(e)))
if not form.errors:
try:
# Create the new components
new_objs = []
with transaction.atomic():
for component_form in new_components:
obj = component_form.save()
new_objs.append(obj)
# Enforce object-level permissions
if self.queryset.filter(pk__in=[obj.pk for obj in new_objs]).count() != len(new_objs):
raise ObjectDoesNotExist
messages.success(request, "Added {} {}".format(
len(new_components), self.queryset.model._meta.verbose_name_plural
))
if '_addanother' in request.POST:
return redirect(request.get_full_path())
elif '_assignip' in request.POST and len(new_objs) >= 1 and request.user.has_perm('ipam.add_ipaddress'):
first_obj = new_objs[0].pk
return redirect(f'/ipam/ip-addresses/add/?interface={first_obj}&return_url={self.get_return_url(request)}')
else:
return redirect(self.get_return_url(request))
except ObjectDoesNotExist:
msg = "Component creation failed due to object-level permissions violation"
logger.debug(msg)
form.add_error(None, msg)
if '_addanother' in request.POST:
return redirect(request.get_full_path())
elif '_assignip' in request.POST and len(self.created_objects) >= 1 and request.user.has_perm('ipam.add_ipaddress'):
first_obj = self.created_objects[0].pk
return redirect(f'/ipam/ip-addresses/add/?interface={first_obj}&return_url={self.get_return_url(request)}')
else:
return redirect(self.get_return_url(request))
return render(request, self.template_name, {
'component_type': self.queryset.model._meta.verbose_name,