2010-09-22 12 views
5

Sto provando a creare un semplice CRUD con ModelForm. Funziona bene tranne che ogni volta che modifico, il salvataggio crea una nuova istanza dei dati. Quindi modifico e ottengo una riga aggiuntiva in DB invece di una aggiornata. Non riesco a capire come sia possibile salvare un'associazione benefica esistente poiché non memorizza il PK (id) come campo nascosto nel modulo. È così che l'ho sempre fatto prima di provare a usare il favoloso ModelForm!Django ModelForm

Mi fa impazzire, ho letto tutto e per quanto posso dire sto facendo tutto bene.

Ecco il mio codice ..

Modello:

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 

Template:

{% 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 %} 

risposta

5

Non funziona perché il modello esegue sempre il POST alla vista che aggiunge un nuovo ente di beneficenza. Quando si digita manualmente un URL come/charities/edit/5, viene creato ModelForm con i dati iniziali corretti, quindi POST to/charities/add, creando così una nuova istanza. Ad esempio, devi POST a/charities/edit/5. Dai un'occhiata al tag del modello di URL.

Suggerisco di utilizzare 2 modelli, uno per l'aggiunta, un altro per la modifica. So che potrebbe non essere molto SECCO, ma credo che sia più chiaro in questo modo.

Add modello:

{% 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 %} 

Modifica modello:

{% 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 %} 

Si consiglia inoltre di controllare il create_object e update_object viste generiche, sono molto utili nei casi più semplici come la tua.

+0

Ciao Tiago, grazie per la risposta. Non avevo mai sentito parlare di generic_update/create views prima. leggerò su di loro. Solo cercando di far funzionare il metodo esistente, non riesco a estrarre l'ID da charity.id in modo da aggiungerlo all'URL di modifica. Ho provato anche form.id ma non è nel contesto. Inoltre, che cos'è charities_app? è questo che metti un segnaposto per me da sostituire? Nella mia vista membro ho provato a utilizzare {% url race.members.views.edit member.id%} ma ho ricevuto l'errore ............... Catturato ViewDoesNotExist durante il rendering: Ho provato a casa in modulo race .charities.views. – Rich

+0

Ho stupidamente dimenticato di poter passare l'ID membro/beneficenza tramite il contesto. Quindi ora ho l'ID nell'URL di modifica e funziona ovviamente. Grazie. Ora sto solo cercando di capire come sostituire l'URL di azione con il tuo esempio {% url charities_app.views.edit charity.id%}. Cos'è charities_app. Dovrebbe essere il percorso per la vista? devo avere get_absolute_url definito? – Rich

+0

Salve, in questo caso charities_app sarebbe il nome dell'app che contiene il modello Charities. charities_app.view.edit è solo il nome della vista che elaborerà la richiesta. Questo tag url è utile perché non devi collegare gli URL nei tuoi template. In questo modo, se scegli di cambiare i mapping url in urls.py, non devi aggiornare i template :) –

Problemi correlati