1

I'm relatively new to django (1.8) and have read around this issue which all points to overriding the save_formset function as per this link

https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.save_formset

Had added to an old thread (Django admin - how to save inlines?) but wanted to raise as a separate thread to get better visibility and besides this already been answered.

The function below works where I'm trying to amend the form before saving it, i.e. updating the audit fields (created/modified) to the USER and lowercase the 'enum_value_en' attribute. All works when user enters just 1 entry but when adding more it updates ALL entries with the SAME value (i.e. 'enum_value_en' in the database.

 def save_formset(self, request, form, formset, change):
    instances = formset.save(commit=False) # gets instance from memory and add to it before saving it
    for obj in formset.deleted_objects:
        obj.delete()
    for instance in instances:
        for form in formset: # cleaned_data is only available on the form, so you have to iterate over formset
            instance.modified_by = request.user
            instance.created_by = request.user
            instance.lowercase_enum_value_en = form.cleaned_data['enum_value_en'].lower()
            instance.save()
    formset.save_m2m()
  • Ex.

    if entries are 'a' & 'b', the lowercase attributes are set to 'b' on both records.

PS. Would also be grateful if anyone could offer some comments around their suggestions so that I can understand each line of code.

Most appreciated.

Community
  • 1
  • 1
Jag Singh
  • 95
  • 2
  • 11

1 Answers1

1

The problem is that you are looping over the instances, and then looping over the formsets within that. Say there are 5 forms, that means you are saving each instance 5 times, once for each instance. Every instance will end up with the same value from the final formset.

In this case, I don't think you need to access the form's cleaned_data. Just access the instance's enum_value_en attribute. This means that you don't need the inner loop that is causing your problem.

for instance in instances:
    instance.lowercase_enum_value_en = instance.enum_value_en.lower()
    instance.modified_by = request.user
    instance.created_by = request.user
    instance.save()
Alasdair
  • 298,606
  • 55
  • 578
  • 516
  • Thank you Alasdair for the solution and explanation - it's worked. I spent an inordinate amount of time trying to resolve this. Frustratingly in our development environment we're using supervisor to restart services and have been trying to use an interactive debugger like Werkzeug but can't. **Can you suggest anything**. Thanks once again. – Jag Singh Aug 05 '16 at 10:08
  • Sorry, I don't have any suggestions about interactive debuggers. – Alasdair Aug 05 '16 at 10:22
  • Thanks all the same. – Jag Singh Aug 05 '16 at 12:57