0

I am trying to delete selected objects in django it works but when I select an item then click delete button it does not delete but after it when I refresh the page selected object is deleted. Here is

views.py

@login_required
def delete_contact(request):
    if request.is_ajax():
        selected_contacts = request.POST['contact_id']
        selected_contacts = json.loads(selected_contacts)

        for i, contact in enumerate(selected_contacts):
            if contact != '':
                ClientContact.objects.filter(author_id__in=selected_contacts).delete()
        return redirect('contacts')

in templates

                 <table class="table table-hover contact-list">
                    <thead>
                    </thead>
                    {% for contact in contacts %}
                        <tbody>
                        <tr data-id="{{ contact.id }}" class="clickable-row"
                            data-href="{% url 'contact-detail' contact.id %}"
                            style="cursor: pointer; ">
                            <th scope="row"><input type="checkbox" id="check"></th>
                            <td>{{ contact.client_name }}</td>
                            <td>{{ contact.client_company_name }}</td>
                            <td>{{ contact.email }}</td>
                            <td>{{ contact.work_phone }}</td>
                            <td>{{ contact.work_phone }}</td>
                        </tr>
                        </tbody>
                    {% endfor %}
                </table>
                {% csrf_token %}
            </div>
        </div>
    </div>
</div>

{% include 'users/footer.html' %}

<script type="text/javascript">
    $(document).ready(function () {
        $(".delete-btn").click(function () {

            var selected_rows = [];

            $('.contact-list').find('tr').each(function () {
                var row = $(this);
                if (row.find('input[type="checkbox"]').is(':checked')) {
                    console.log(row.attr('data-id'));
                    selected_rows.push(row.attr('data-id'));
                }

            });
            var selected_rows = JSON.stringify(selected_rows);
            $.ajax({
                url: "{% url 'contact-delete' %}",
                type: 'POST',
                data: {
                    'contact_id': selected_rows,
                    'csrfmiddlewaretoken': $("[name=csrfmiddlewaretoken]").val()
                },
            });
        });
    });
</script>

it works fine but with refreshing the page. How can I delete selected objects as soon as I click the delete button. Any help please? Thank you!

2 Answers 2

2

You are deleting the objects, what you are missing is that after sending the request to Django, if the request is successful you need to update the HTML accordingly.

The HTML of your page is rendered when you request the view. At this point the for loop in your template gets executed and iterates over all existing contacts

{% for contact in contacts %}               
{% endfor %}

Afterwards, when the user clicks the delete button a request is sent through AJAX to Django which effectively deletes the selected objects yet the HTML code is not updated automagically. When you refresh the page, the template code is executed once more by Django and thus the for loop is run again but this time the list of contacts has changed, that's why you see the changes in this case.

You can solve your issue in different ways:

1) Instead of calling a Django view via AJAX, make a proper HTML+Django form that is posted to a Django view that after processing the form redirects to the same view again. This would require no Javascript or AJAX. You can read more about forms here. In this way your template is re-rendered after every post and therefore you will see your table updated.

2) Probably the worst option, but also the easiest to implement at this point, would be to refresh your page via Javascript after the AJAX request returns successfully. For this you can bind a function to the success property of your $.ajax call that triggers a refresh, something like location.reload();. Note that this is not a good choice since you are making all the effort to call the delete view using AJAX but you are not getting any of its benefits, getting only the worst of both worlds.

3) The third option is to edit your HTML (your DOM actually) using javascript when the AJAX call returns successfully. If you choose to follow this path (which is your intention I presume) and do not know how to do it I suggest that you post another question regarding specifically how to change the rendered HTML via Javascript.

Sign up to request clarification or add additional context in comments.

Comments

0

django actually call for every related model pre_delete and post_delete signals. So calling some function for every related models was found not inefficient. And I think, that not calling delete() method leads to destroy the integrity of data. For example: we have model myModel with FileField. In case, when we call delete() from some of myModel's object, this object and related file will be deleted. If we call delete of related to myModel's object, this object will be deleted, but file will remain.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.