#12087 - Fix Bulk Edit update when M2M operations are present. (#12169)

* #12087 - Fix Bulk Edit update when M2M operations are present.

* #12087 - Minor tweaks

* Change .set() to .clear()

Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>

* #12087 - Update comments

---------

Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
This commit is contained in:
Daniel Sheppard 2023-04-05 12:29:32 -05:00 committed by GitHub
parent 94c2a2e56c
commit 41c92483a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -500,6 +500,21 @@ class BulkEditView(GetReturnURLMixin, BaseMultiObjectView):
]
nullified_fields = request.POST.getlist('_nullify')
updated_objects = []
model_fields = {}
m2m_fields = {}
# Build list of model fields and m2m fields for later iteration
for name in standard_fields:
try:
model_field = self.queryset.model._meta.get_field(name)
if isinstance(model_field, (ManyToManyField, ManyToManyRel)):
m2m_fields[name] = model_field
else:
model_fields[name] = model_field
except FieldDoesNotExist:
# This form field is used to modify a field rather than set its value directly
model_fields[name] = None
for obj in self.queryset.filter(pk__in=form.cleaned_data['pk']):
@ -508,25 +523,10 @@ class BulkEditView(GetReturnURLMixin, BaseMultiObjectView):
obj.snapshot()
# Update standard fields. If a field is listed in _nullify, delete its value.
for name in standard_fields:
try:
model_field = self.queryset.model._meta.get_field(name)
except FieldDoesNotExist:
# This form field is used to modify a field rather than set its value directly
model_field = None
for name, model_field in model_fields.items():
# Handle nullification
if name in form.nullable_fields and name in nullified_fields:
if isinstance(model_field, ManyToManyField):
getattr(obj, name).set([])
else:
setattr(obj, name, None if model_field.null else '')
# ManyToManyFields
elif isinstance(model_field, (ManyToManyField, ManyToManyRel)):
if form.cleaned_data[name]:
getattr(obj, name).set(form.cleaned_data[name])
setattr(obj, name, None if model_field.null else '')
# Normal fields
elif name in form.changed_data:
setattr(obj, name, form.cleaned_data[name])
@ -544,6 +544,13 @@ class BulkEditView(GetReturnURLMixin, BaseMultiObjectView):
obj.save()
updated_objects.append(obj)
# Handle M2M fields after save
for name, m2m_field in m2m_fields.items():
if name in form.nullable_fields and name in nullified_fields:
getattr(obj, name).clear()
else:
getattr(obj, name).set(form.cleaned_data[name])
# Add/remove tags
if form.cleaned_data.get('add_tags', None):
obj.tags.add(*form.cleaned_data['add_tags'])