Joar
Joar

Reputation: 23

django delete object from post (bootstrap)

I'm trying to implement a way to delete objects from frontend using a form and Bootstrap. The alert box is closing but upon page refresh the object is still present and no deletion is made in database.

What's the proper way of implementing this? Please help!

forms.py

 class DeleteAlertForm(forms.ModelForm):
      def is_valid(self):
        form = super(DeleteAlertForm, self).is_valid()
        for f, error in self.errors.iteritems():
          if f != '__all__':
            self.fields[f].widget.attrs.update({'class': 'error', 'value': strip_tags(error)})
        return form

  class Meta:  
    model = Alert
    fields = []

views.py

@login_required
def delete(request, alert_id):
  if request.method == "POST":
    form = DeleteAlertForm(request.POST)
    if form.is_valid(): # checks CSRF
      a_id = request.POST.get('alert_id', False)
      alert = New.objects.get(pk=a_id)
      alert.delete()
      return HttpResponseRedirect("/")
  else:
    return redirect('/')
  return redirect('/')

template.html

<div class="alert alert-info alert-block">
<form action="/delete/" method="post">
{% csrf_token %}
<input type="hidden" value="{{alert.id}}" name="alert_id">
<button type="submit" class="close" data-dismiss="alert">×</button>
</form>
</div>

urls.py

url(r'^$/(?P<pk>\d+)/delete$', login_required(DeleteView.as_view(
model=Alert,
success_url='/',
template_name='portal/alert_confirm_delete.html',))),

Upvotes: 2

Views: 1199

Answers (2)

Lorenz Lo Sauer
Lorenz Lo Sauer

Reputation: 24740

You can easily use Django with your own delete-template using bootstrap.
As the user-interface and redirection are described to be as intended, the error appears that you have set the wrong model: New in your delete action, which became clear after you updated/posted your revised urls.py. The model on which to run delete should be Alert

In your delete action a queryset comprised of an entry corresponding to the primary key of New-entries is selected as being equal to alert_id.

  alert = New.objects.get(pk=a_id)

The intended Model should likely be Alert

To fetch entries from your Model New using Alert entries, set a ForeignKey relationship in the Model New as follows. For instance:

class New(models.Model):
  alert = models.ForeignKey(Alert, verbose_name=_("Alert posts"))
  ....

Django's Object-Relational-Mapper will thus create a datebase field called alert_id with the proper relationship CONSTRAINTS and ForeignKeys.

Don't forget to run syndb on the shell afterwards. e.g. using manage.py syndb

Django probably threw a DoesNotExist exception similar to the one shown:

In [2]: appname.models.New.objects.get(pk=-1)
---------------------------------------------------------------------------
DoesNotExist                              Traceback (most recent call last)
/usr/local/lib/python2.6/dist-packages/django/core/management/commands/shell.pyc in <module>()
----> 1 lead.models.Lead.objects.get(pk=-1)

/usr/local/lib/python2.6/dist-packages/django/db/models/manager.pyc in get(self, *args, **kwargs)
    129
    130     def get(self, *args, **kwargs):
--> 131         return self.get_query_set().get(*args, **kwargs)
    132
    133     def get_or_create(self, **kwargs):
....
DoesNotExist: Lead matching query does not exist.

Whilst Django is setup by default to show you exceptions if DEBUG is turned on in settings.py, you instantly redirected within your code and did not handle/output exceptions.

Exceptions should still be logged by default, and written to a log file whose location depends on the server you are running.

You can set up log-handling in your project's settings.py using the variable LOGGING = {...}. See the Django manual on logging.

Upvotes: 2

Matthew Daly
Matthew Daly

Reputation: 9476

Have you considered using a DeleteView?

He're's how you might implement a URL for this:

    url(r'^mymodel/(?P<pk>\d+)/delete/$', login_required(DeleteView.as_view(
        model=MyModel,
        success_url="/mymodel/deleted/",
        template_name="myapp/mymodel_confirm_delete.html",
    ))),

You would need to implement something similar for each model you want to be able to delete. However, the only other code you would need in your urls.py is importing DeleteView. You could use the same template and success URL for all of your models, however.

Upvotes: 2

Related Questions