How to render multiple update forms in Django

Viewed 39

here is my problem.

I have a list of objects that I display in a table and all works just fine except that I would like to edit them inside a modal and submit them using AJAX.

I though that it was a simple idea to render, for each row, a form with the inputs pre-filled and then submit the selected form with AJAX.

I wonder if there is a relatively simplified way to render the UpdateForm without writing manually all the input fields.

Something like this:

<table>
{% for transaction in transactions %}
<tr>
<td>{{ transaction.date|date:"d.m.Y" }}</td>
<td>{{ transaction.amount }}</td>
<td>
  <a href="#" data-bs-toggle="modal" data-bs-target="#edit{{ transaction.id }}">Edit</a>
 <div class="modal" id="edit{{ transaction.id }}">
   {{ transaction_form }}
 </div>
</td>
<tr>
{% endfor %}
</table>

But how can I pass the form from the view?

The way I'm currently doing it is that when the user click on edit the page refresh and the modal is displayed with the form prefilled but it is (a) slow to open and (b) I don't think it is a nice way to do it.

This is my current code

views.py


class ProjectDetailView(DetailView):
    model = Project
    template_name = "template.html"
    context_object_name = "project"


    def get_transactions(self):
        transactions = Transaction.objects.filter(project=self.get_object())
        return transactions

    def get_transaction_form(self):
        form = TransactionForm()
        if self.request.POST:
            form = TransactionForm(self.request.POST)
        elif 'edit_entry' in self.request.GET:
            form = TransactionForm(instance=self.get_entry())
        return form

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['transactions'] = self.get_transactions()
        context['transaction_form'] = self.get_transaction_form()
        return context

template.html

<table>
{% for transaction in transactions %}
<tr>
<td>{{ transaction.date|date:"d.m.Y" }}</td>
<td>{{ transaction.amount }}</td>
<td>
  <a href="{{ project.get_absolute_url }}?edit_entry={{ transaction.slug }}">Edit</a>
</td>
<tr>
{% endfor %}
</table>
<div class="modal" id="edit-modal">
   {{ transaction_form }}
</div>
<script>
{% if 'edit_entry' in request.GET %}
  $('#edit-modal').modal('show')
{% endif %}
</script>

Thank you for any feedback

1 Answers

This solution needs you work with Javascript to do that, when the user clicks 'Edit' for an object on your page,

  1. you send AJAX request (using Fetch API or Jquery) to your view,
  2. The view will return HTML of the form and you put this HTML in the modal's body
  3. Show the modal with an action button to submit the form.
  4. As the user clicks submit, your code submits the form through Ajax, you can use Formdata or AjaxForm for that, the view which return an JSON or HTML which indicates if the data is saved successfully or not.

The problem I'm not a Class-Based View guy so I can't give you specifics from Django side.

Related