2014-10-02 5 views
6

Ich habe ein Projekt mit einem Post-Modell, das ist grundlegende Beiträge. Ich möchte auf jeder Post-Seite einen Link erstellen, um diesen Beitrag löschen zu können (mit entsprechender Sicherheit).Löschen von Objekten in Django über HTML-Link

Es gibt ein paar Fragen zu diesem On-Stack-Überlauf, aber ich kann keine vollständige, praktikable Antwort finden (ich benutze Django 1.7), die keine Fehler hervorbringt, wenn ich sie implementiere.

Ich konnte eine Löschfunktion implementieren, die funktioniert, aber Sie müssen ein POST-Formular mit CSRF-Token für die Überprüfung hinzufügen, und überprüfen Sie auch, dass der Benutzer löschen es ist, der es erstellt hat. Ich kann nicht scheinen, herauszufinden, wie sich diese beiden in

Bisher in meinem views.py hinzuzufügen:.

def delete(request, id): 
    post = Post.objects.filter(pk=id).delete() 
    return HttpResponseRedirect(reverse('posts.views.all_posts')) 

In urls.py:

url(r'^delete/(?P<id>\d+)/$','posts.views.delete'), 

In html:

<a href="/delete/{{ post.id }}">Delete</a> 

Das alles funktioniert, aber es gibt keine Sicherheit - so schätzen Anleitung, wie Sie ein Formular hinzufügen und überprüfen.

Außerdem habe ich eine Antwort gesehen, die DeleteView verwendet, aber auch nicht funktionieren konnte.

+0

Ich möchte nur klären, ob die Benutzer müssen angemeldet sein, um alle Beiträge sehen zu können? – catherine

Antwort

8

In der Tat macht die Verwendung einer GET-Methode zum Löschen Ihrer Objekte Sie anfällig für CSRF attacks.

DeleteView löscht nur beim POST und zeigt eine Bestätigungsseite bei GET an.

Der Code sollte in views.py etwa wie folgt aussehen:

from django.views.generic import DeleteView 

class PostDelete(DeleteView): 
    model = Post 
    success_url = reverse_lazy('posts.views.all_posts') 

In urls.py:

url(r'^delete/(?P<pk>\d+)/$', PostDelete.as_view(), 
     name='entry_delete'), 

Ihre Form (ohne eine Bestätigung Vorlage Es ist ein Beispiel Bestätigungsvorlage in der Dokumentation.):

<form action="{% url 'entry_delete' object.pk %}" method="post"> 
    {% csrf_token %} 
    <input type="submit" value="Delete" /> 
</form> 

Wenn Sie nicht sind Stellen Sie mithilfe einer Bestätigungsvorlage sicher, dass das Attribut action des Formulars auf DeleteView (this is why) verweist.

Um sicherzustellen, dass der Benutzer den Beitrag löscht ist der Benutzer, der es besitzt, verwende ich gerne mixins. Angenommen, Ihr Post Modell ein created_by Fremdschlüssel zeigt auf User hat, könnten Sie eine mixin wie schreiben:

from django.core.exceptions import PermissionDenied 

class PermissionMixin(object): 

    def get_object(self, *args, **kwargs): 
     obj = super(PermissionMixin, self).get_object(*args, **kwargs) 
     if not obj.created_by == self.request.user: 
      raise PermissionDenied() 
     else: 
      return obj 

Schließlich Ihre DeleteView sollten von dieser mixin erben:

class PostDelete(PermissionMixin, DeleteView): 

    model = Post 
    success_url = reverse_lazy('posts.views.all_posts') 
+0

Brilliant, das hat perfekt funktioniert - ich habe es ohne Bestätigungsbildschirm versucht und es funktioniert wirklich gut. Ich werde jetzt versuchen, den Bestätigungsbildschirm hinzuzufügen. –

+0

Für alle, die dies in Zukunft betrachten, müssen Sie auch PostDelete in Ihre URLs.py importieren, zB: aus Ansichten importieren PostDelete –

Verwandte Themen