Search code examples
djangopython-3.xdjango-formsmodelform

Django modelformset_factory deleting objects marked by can_delete


Hello I have got question I have made modelformset_factory and in options I have choosen can_delete = True and now I don't know how to delete marked objects as 'DELETE' : True to delete them from database. I was trying to do this in some ways and it didnt work. I was looking for it also in django formsetmodels documentation but this didnt help me. With this option can_delete = True I get additional checkbox in my html page Delete and marking him only prints me in console on print: {'username': 'sw', 'email': '[email protected]', 'city': 'ss', 'code': 12345, 'id': , 'DELETE': False}

Saving forms to database is working but I dont know how to delete marked forms from database.

I would be very thankful for every help.

I have made modelformset_factory from model in models.py

class TestModel(models.Model):
username = models.CharField(max_length=120)
email = models.EmailField()
city = models.CharField(max_length=120)
code = models.IntegerField()
#W admin panelu za miast TestModel object bedzie username
def __str__(self):
    return self.username

Then I have added in my views.py function:

def django_modelformset(request):
TestModelFormset = modelformset_factory(TestModel, fields=['username', 'email', "city",
                                                           "code"], extra=1, can_delete=True)
formset = TestModelFormset(request.POST or None)

if formset.is_valid():
    for form in formset:
        print(form)

        print(form.cleaned_data)
        form.save()
context = {"formset": formset}
return render(request, "modelformset.html", context)

My modelformset.html looks like this:

<form method="POST" action="">
{% csrf_token %}

{{ formset.management_form}}
{% for form in formset %}
<div>

    {{ form.as_p }}
    <hr/>
</div>
{% endfor %}
<input type="submit" value="Save">


Solution

  • I haven't personally had to do this, but from the docs it seems you have a few options.

    1. Call save on the formset instead of each form.

      if formset.is_valid():
          formset.save()
      
    2. If you must loop through each form you could something like this.

      if formset.is_valid():
         for form in formset:
             print(form.cleaned_data)
             if form.cleaned_data["DELETE"]:
                 # Do what you want with the form data
                 # i.e. get the object from the database and delete it.
             else:
                 form.save()
      
    3. Loop through the deleted forms separately.

      if formset.is_valid():        
          forms = formset.save(commit=False)
          for object in formset.deleted_objects:
              object.delete()