0

I have the following form displaying entries of a model for user settings. When selected, I would like that a button catches its pk and send it to a Delete view.Here is the current code but I am missing this part.

user_detail template html

                <form id="SettingsListForm"><label>&nbsp Settings List : &nbsp &nbsp &nbsp</label>
                    {% if user.usersetting.first %}
                        <select class="form-control" name="settingslist" id = "settingslist" form="SettingsListForm" >
                            {% for settings in user.usersetting.all %}      
                                    <option value="{{ settings.file.url }}">{{ settings }} 
                                    </option>

                            {% endfor %}
                        </select>
                    {% else %}
                        <li class="list-group-item">NO SETTINGS YET</li>
                    {% endif %}
                    <button class="btn btn-outline-light btn-circle"><i class="glyphicon glyphicon-minus" href="{% url 'my_app:setting_delete' pk=user.usersetting.last.id %}"></i></button>

                    {% block delete_setting_confirm_block %}

                    {% endblock %}
                </form>

setting_confirm_delete html template with delete_setting_confirm_block

{% extends 'login_app/user_detail.html' %}
{% block delete_setting_confirm_block %} 
    <h4> 
        ARE YOU <b>REALLY</b> SURE YOU WANT TO <b>DELETE</b> THIS SETTING ?
        <form method="POST">
            {% csrf_token %}
            <button type="submit" class="btn btn-outline-light btn-danger" value="Delete">YES</button>
            <a class="btn btn-outline-light btn-default" href="{% url 'login_app:user_detail' pk=user.id %}"><b>NO</b></a>
        </form>
    </h4>
{% endblock %}

my_app urls

url(r'^setting/(?P<pk>\d+)/$',views.UserSettingDeleteView.as_view(),name='setting_delete'),

UserSettingDeleteView in my_app views

class UserSettingDeleteView(DeleteView):

    model = models.UserSetting
    template_name = 'my_app/setting_confirm_delete.html'

    def get_success_url(self):
        return reverse('my_app:user_detail', kwargs={'pk': self.object.user.pk})

Somehow, a similar technique works fine when using listgroups:

working sample in user_detail html

        <ul class="list-group">
            {% if user.userdata.first %}
                {% for data in user.userdata.all %}
                    <li class="list-group-item">{{ data }}<a class="btn btn-outline-light btn-circle" href="{% url 'my_app:data_delete' pk=data.pk %}"><i class="glyphicon glyphicon-remove"></i></a><a href="{{ data.file.url }}" class="btn btn-outline-light btn-circle" download><i class="glyphicon glyphicon-save"></i></a></li>
                {% endfor %}
                {% block delete_data_confirm_block %}

                {% endblock %}
            {% else %}
                <li class="list-group-item">NOTHING RECORDED YET</li>
            {% endif %}

        </ul>
compmonks
  • 647
  • 10
  • 24

3 Answers3

0

In your template.html, you should create a form for deletion, like this:

<form action="{% url 'my_app:setting_delete' pk=user.usersetting.last.id %}" method="post">
    {% csrf_token %}
    <input type="submit" value="Delete" class="btn btn-outline-light btn-circle">
</form>

Because in HTML you can not send directly PUT or DELETE, you should fake it via a POST request. It will be useful to read this, it is explained well.

Your UserSettingDeleteView can be as simple as that:

from django.views.generic.edit import DeleteView
from django.urls import reverse_lazy


class UserSettingDeleteView(DeleteView):
    model = MyModel
    # Replace with the model you want to delete (User)

    success_url = reverse_lazy('my_app:setting_list')
    # After deletion, possibly you will want to redirect the user to the list view

The built-in DeleteView cares itself to find your model by the pk parameter you pass through your url and delete it, you just have to configure the model and success_url fields.

Now if you click on your Delete button, you should expect your desired entry to be deleted and the user to be redirected to the list view.

EDIT:

I forgot that you want to get this entry via options. Here you will have to use some JavaScript in order to find the currently selected element and send it's pk to your DeleteView.

At first, add id's to your option tags, like this:

<select class="form-control" name="settingslist" id="settingslist" form="SettingsListForm">
    {% for settings in user.usersetting.all %}      
        <option value="{{ settings.file.url }}" id="{{ settings.id }}">{{ settings }}</option>
    {% endfor %}
</select>

And then add some jQuery:

var settingId = $('#SettingsListName').find(":selected").attr('id');

In the end, you need to send settingId to the corresponding url, but I am not very familiar with JavaScript.

wencakisa
  • 5,850
  • 2
  • 15
  • 36
  • Hi @wencakisa, thanks for the comment. I have tried something similar you are suggesting but the problem seems to be with getting the pk of the selected element in the 'select' component. I just edited my question with more detailed code. – compmonks Aug 19 '17 at 11:12
0

Try putting a hidden input in your form. Right now, nothing is passing through the form.

<input type="hidden" name="del_setting" value="{{user.usersetting.last.id}}">

So your form would look like this

<form method="POST"> 
{% csrf_token %} 
  <input type="hidden" name="del_setting" value="{{user.usersetting.last.id}}">
  <button type="submit" class="btn btn-outline-light btn-danger" value="Delete">YES</button>
  <a class="btn btn-outline-light btn-default" href="{% url 'login_app:user_detail' pk=user.id %}"><b>NO</b></a> 
</form>

You also probably should move this out of the current form in your user detail template so that you're not putting a form within a form:

{% block delete_setting_confirm_block %}
{% endblock %}
csling
  • 326
  • 1
  • 8
0

None of the previously mentioned solutions would work so I guess the problem is the nested bootstrap select item which is supposed to display the pk of the setting. For simplicity I then removed the problem by using list-group instead

                <ul class="list-group">
                    {% if user.usersetting.first %}
                        {% for settings in user.usersetting.all %}
                            <li class="list-group-item">{{ settings }}<a class="btn btn-outline-light btn-circle" href="{% url 'my_app:setting_delete' pk=settings.pk %}"><i class="glyphicon glyphicon-remove"></i></a></li>
                        {% endfor %}
                        <label>Create a new setting...</label>
                        <a class="btn btn-outline-light btn-circle"><i class="glyphicon glyphicon-plus"></i></a>
                    {% else %}
                        <li class="list-group-item">Create a new setting...<a class="btn btn-outline-light btn-circle"><i class="glyphicon glyphicon-plus"></i></a></li>
                    {% endif %}
                    {% block delete_setting_confirm_block %}

                    {% endblock %}
                </ul>

As a workaround,this works well.

compmonks
  • 647
  • 10
  • 24