Reputation: 12064
I have model as follows:
class BusinessUnitGroup(models.Model):
name = models.CharField(max_length=255)
business_units = models.ManyToManyField(to=BusinessUnit, blank=True, null=True)
capacity = models.IntegerField(null=True, blank=True)
def __unicode__(self):
return self.name
Now in an view I have fields with group id's where the business unit needs to be added. From the other one it needs to be remove if it exists. I do it as follows:
business_unit = get_or_none(BusinessUnit, id=business_unit_id)
# Groups
old_groups = BusinessUnitGroup.objects.exclude(id__in=form_data['groups'])
for group in old_groups:
group.business_units.remove(business_unit)
new_groups = BusinessUnitGroup.objects.filter(id__in=form_data['groups'])
for group in new_groups:
group.business_units.add(business_unit)
Where form_data['groups']
is an param and it's just a list of ids [1, 2, 3]
That works fine, but is there any better way to do it?
UPDATE
@transaction.commit_on_success
def handle_edit_business_unit(form_data, company_id, business_unit_id):
if not form_data:
return {'result': 'nok', 'message': 'The form data is not provided.'}
try:
business_unit = get_or_none(BusinessUnit, id=business_unit_id)
if business_unit:
business_unit.name = form_data['name']
business_unit.save()
# Groups
business_unit.businessunitgroup_set.set(form_data['groups'])
return {'result': 'ok', 'message': ''}
except Exception as err:
# TODO Log error message somewhere
print(str(err))
return {'result': 'nok', 'message': 'The business unit could not be handled. Please try again.'}
Upvotes: 4
Views: 637
Reputation: 476557
Yes, you can work with .set(…)
[Django-doc]:
business_unit = get_or_none(BusinessUnit, id=business_unit_id)
business_unit.businessunitgroup_set.set(form_data['groups'])
We here thus work with the ManyToManyField
in reverse. Instead of altering the BusinessUnitGroup
s by removing or adding a business_unit
. We simply set the businessunitgroup_set
s of the business_unit
.
By setting the many-to-many field that way, this normally should work with two queries: one to remove all the items not in forms_data['groups']
, and one that adds the form_data['groups']
to the business_unit
.
Upvotes: 2