Reputation: 188
I am out of ideas and I need some help about a problem that I encounter when I try to save the same object. Let me explain.
I have a model, let's call it Pizza. And Topping which has a foreign key to Pizza:
I have implemented an Admin view PizzaAdmin and I have added a tabular inline of Topping
so from PizzaAdmin, I can add several toppings.
I have override the save_formset method where I call a helper to perform a third-party API call. From the API response, I need to save some data to my toppings.
def save_formset(self, request, form, formset, change):
super(PizzaAdmin, self).save_formset(request, form, formset, change)
helper = ApiHelper(instance=form.instance)
helper.sync()
This helper makes a call to an API, parse the response and associate an ID for each toppings of Pizza.
class ApiHelper(...):
def sync(self):
# parse response
for topping in self.instance.toppings.all():
if ....:
topping.some_id = ...
topping.save()
When I reach the topping.save()
, I got this error: IntegrityError
I do not want to create a new Topping but update its property some_id
.
After futher investigation, I realised that save_formset
is called by save_related
which is called by changeform_view
which as the decorator @transaction.atomic
Is there a way to force the commit inside an atomic transaction ?
Please advise. Thanks a lot.
*** UPDATE: 2017-03-30 ***
I have found transaction.on_commit() which allows me to perform actions after the commit:
class PizzaAdmin(admin.ModelAdmin)
def save_formset(self, request, form, formset, change):
super(PizzaAdmin, self).save_formset(request, form, formset, change)
transaction.on_commit(lambda: sync_toppings(instance=form.instance))
def sync_toppings(instance):
helper = ApiHelper(instance=form.instance)
helper.sync()
Inside sync() method, I have replace my queryset using this logic:
toppings_qs = Topping.objects.filter(pizza=self.instance)
I still have an IntegrityError when I try to update the topping through the queryset.
I do not understand why. Please help.
Upvotes: 0
Views: 251
Reputation: 188
I have found my mistake!!! This is what I did:
def save(self, **kwargs):
self.is_negative = True
super(Topping, self).save(self, **kwargs)
Notice the self in save of the super() :(
My fix:
def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
self.is_negative = True
super(Topping, self).save(force_insert, force_update, using, update_fields)
Upvotes: 0