2010-06-26 10 views
18

En una aplicación de mini blog, quiero crear una función de eliminación para que el propietario del blog pueda eliminar sus entradas (y solo sus entradas). Supongo que los únicos métodos para hacerlo, es usar un formulario. Aunque mi código de borrado parece claro y correcto, no funciona. Mi código:Eliminación de objetos en Django

def delete_new(request,id): 
    u = New.objects.get(pk=id).delete() 
    if request.method == 'POST': 
     form = DeleteNewForm(request.POST)  
     form.u.delete()    
     form.save() 
    return render_to_response('news/deleteNew.html', { 
      'form': form, 
      }, 
     context_instance=RequestContext(request)) 

y en la plantilla:

<a href='/news/delete_new/{{object.id}}/'> Delete</a> <br /> 

Es este un enfoque correcto? Quiero decir, ¿crear una forma para esto? también, la única forma de tomar la publicación de blog asociada con el enlace de eliminación es tener una identificación como parámetro. ¿Es correcto? Quiero decir, tal vez cualquier usuario puede escribir otra identificación, en la url, y eliminar otra entrada (eventualmente no una de las suyas)

Respuesta

16

En general, para eliminar objetos, debe usar POST (o ELIMINAR) HTTP methods.

Si realmente desea utilizar HTTP GET para el ejemplo, esto es lo que debe arreglar:

Si tiene URL que apunta a cierta URL como la suya: <a href='/news/delete_new/{{object.id}}/'> Delete</a> entonces simplemente puede escribir vista que va a comprobar si objeto pertenece al usuario conectado y eliminar esta entrada si es así, como en el código que ya ha escrito:

def delete_new(request,id): 
    #+some code to check if New belongs to logged in user 
    u = New.objects.get(pk=id).delete() 

para comprobar si los nuevos objetos belogs a algún usuario que necesita para crear realation entre User y New (como created_by = models.ForeignKey(User) en Modelo New).

Usted puede obtener usuario conectado de esta manera: request.user

espero que me dieron su punto de forma correcta y mi respuesta le ayuda de alguna manera.

PD: También puede considerar usar la etiqueta {% url %} en lugar de escribir urls directamente en sus plantillas.

+0

que rueda sin problemas, y en una sola línea: u = New.objects. filter (created_by = request.user) .get (pk = id) .delete() ¡gracias! :) – dana

+0

Exactamente, puede agregar algún control de errores si no hay tal objeto nuevo para un usuario dado y mostrar un buen mensaje de error (con su trazador de líneas, fallará ruidosamente con error de 500). Pero básicamente eso es todo lo que debes hacer aquí :) Me alegra que mi respuesta haya sido útil para ti. – dzida

+20

Recomiendo encarecidamente usar un formulario y verificar POST, porque se supone que GETs a páginas no cambian el estado en el servidor. (Aunque, en la práctica, lo que está sucediendo aquí es relativamente "seguro") –

23

Es necesario utilizar un formulario, o que son vulnerables a CSRF attacks. También está eliminando el modelo antes de verificar si la solicitud fue GET o POST.

Crear un simple ModelForm:

from django import forms 

from .models import New 

class DeleteNewForm(forms.ModelForm): 
    class Meta: 
     model = New 
     fields = [] 

En su views.py en la misma aplicación de Django:

from django.shortcuts import render, get_object_or_404 

from .forms import DeleteNewForm 
from .models import New 

def delete_new(request, new_id): 
    new_to_delete = get_object_or_404(New, id=new_id) 
    #+some code to check if this object belongs to the logged in user 

    if request.method == 'POST': 
     form = DeleteNewForm(request.POST, instance=new_to_delete) 

     if form.is_valid(): # checks CSRF 
      new_to_delete.delete() 
      return HttpResponseRedirect("/") # wherever to go after deleting 

    else: 
     form = DeleteNewForm(instance=new_to_delete) 

    template_vars = {'form': form} 
    return render(request, 'news/deleteNew.html', template_vars) 
+6

Explicar por qué esto es lo mejor: en CUALQUIER CASO, los envíos, las actualizaciones y las eliminaciones DEBEN usar solicitudes POST (o PUT). Las solicitudes GET pueden enmascararse en enlaces que de otra manera serían inofensivos. Digamos, si un sitio principal tiene un simple "Eliminar todas mis cosas" en example.com/account/delete/, podría ocultar dicho enlace en una publicación de blog o en servicios similares a TinyURL. Después de la visita, verá un buen "Su perfil fue eliminado". página. Métodos híbridos como Wilfred Hughes ', muestran una página de confirmación en GET, que contiene un formulario con un token CSRF. Las solicitudes POST validan CSRF y finalmente eliminan el recurso solicitado. – sleblanc

Cuestiones relacionadas