2010-09-22 14 views
5

Estoy tratando de crear un CRUD simple con ModelForm. Funciona bien, excepto que cada vez que edito, el guardado crea una nueva instancia de los datos. Así que edito y obtengo una fila adicional en DB en lugar de una actualizada. No sé cómo se puede guardar una organización benéfica existente, ya que no almacena PK (id) como un campo oculto en el formulario. ¡Así es como siempre lo hice antes de tratar de usar el "fabuloso" ModelForm!Django ModelForm

Me está volviendo loco, lo he leído todo y, por lo que sé, estoy haciendo todo bien.

Aquí está mi código ..

Modelo:

from django.db import models 
from django.conf import settings 

COUNTRY_CHOICES = settings.COUNTRIES 

class Charities(models.Model): 
    charity_name   = models.CharField(max_length=100) 
    country     = models.CharField(max_length=4, choices=COUNTRY_CHOICES) 
    registration_number  = models.CharField(max_length=100) 
    address1    = models.CharField(max_length=100) 
    address2    = models.CharField(max_length=100) 
    city     = models.CharField(max_length=30) 
    zip      = models.CharField(max_length=10) 
    phone     = models.CharField(max_length=20) 
    email     = models.EmailField() 
    charity_logo_image  = models.CharField(max_length=100) 
    charity_banner_image = models.CharField(max_length=100) 
    charity_accepted  = models.IntegerField() 

    def __str__(self): 
     return self.charity_name 

    def __unicode__(self): 
     self.charity_name 

Vista:

def list(request): 
    charities = Charities.objects.all() 
    return render_to_response('charities_charity_list.html', {'charities': charities}) 

def add(request): 
    return add_or_edit(request) 

def edit(request, charity_id): 
    return add_or_edit(request, charity_id) 

def add_or_edit(request, charity_id=None): 
    print "ID = " + str(charity_id) 
    form = CharityForm(request.POST or None, 
        instance=charity_id and Charities.objects.get(pk=charity_id)) 

    # Save new/edited student 
    if request.method == 'POST' and form.is_valid(): 
     print form 
     form.save() 
     return HttpResponseRedirect('/charities/list/') 

    return render_to_response('charities_charity_edit.html', {'form': form}) 

Forma:

class CharityForm(ModelForm): 
    class Meta: 
     model = Charities 

Plantilla:

{% extends "base.html" %} 

{% block title %}Charities Add{% endblock %} 
{% block content %} 

<form method="post" action="/charities/add/" id="save"><table cellpadding="0">{{ form.as_table}}</table><input type="submit" value="Save"></form> 
{% endblock %} 

Respuesta

5

No funciona porque su plantilla siempre está PUBLICANDO en la vista que agrega una nueva Caridad. Cuando escribe manualmente una URL como/caridades/editar/5, crea ModelForm con los datos iniciales correctos, pero luego envía los mensajes a/caridades/agregar, creando así una nueva instancia. Necesita enviar a/caridades/editar/5, por ejemplo. Eche un vistazo a la etiqueta de la plantilla de URL.

Le sugiero que use 2 plantillas, una para agregar, otra para editar. Sé que puede no ser muy seco, pero creo que está más claro de esta manera.

Agregar plantilla:

{% extends "base.html" %} 

{% block title %}Charities Add{% endblock %} 
{% block content %} 

<form method="post" action="{% url charities_app.views.add %}"><table cellpadding="0">{{ form.as_table}}</table><input type="submit" value="Save"></form> 
{% endblock %} 

Editar plantilla:

{% extends "base.html" %} 

{% block title %}Edit Charity{% endblock %} 
{% block content %} 

<form method="post" action="{% url charities_app.views.edit charity.id %}"><table cellpadding="0">{{ form.as_table}}</table><input type="submit" value="Save"></form> 
{% endblock %} 

También es posible que desee comprobar la create_object y update_object vistas genéricas, que son muy útiles en casos simples como la suya.

+0

Hola Tiago, gracias por responder. No había oído hablar de generic_update/create views antes. Voy a leer sobre ellos. Solo intentando que el método existente funcione, parece que no puedo extraer la ID de charity.id para adjuntarla a la URL de edición. Intenté form.id también pero no está en contexto. Además, ¿qué es caridades_app? ¿Esto es solo poner un marcador de posición para que lo sustituya? En mi vista de miembro, traté de usar {% url race.members.views.edit member.id%} pero obtuve el error ............... Atrapado ViewDoesNotExist durante la representación: Intenté mi casa en la carrera de módulos .charities.views. – Rich

+0

Olvidé estúpidamente que podía pasar la identificación de miembro/caridad en el contexto. Entonces ahora tengo la ID en la URL de edición y funciona, por supuesto. Gracias. Ahora solo trato de entender cómo reemplazar la URL de acción con similar a su ejemplo {% url charities_app.views.edit charity.id%}. ¿Qué es caridades_app? ¿Debería ser el camino a la vista? ¿Necesito tener get_absolute_url definido? – Rich

+0

Hola, en este caso, charities_app sería el nombre de la aplicación que contiene el modelo de Charities. charities_app.view.edit es solo el nombre de la vista que va a procesar la solicitud. Esta etiqueta de URL es útil porque no necesita conectar las URL en sus plantillas. De esta forma, si elige cambiar las asignaciones de URL en urls.py, no necesita actualizar las plantillas :) –

Cuestiones relacionadas