2009-06-01 19 views
44

Sto provando a prepopolare i dati nel mio modulo django sulla base di alcune informazioni, ma NON utilizzando ModelForm, quindi non posso semplicemente impostare l'istanza.Prepopolare il modulo Django (non-Model)

Sembra che dovrebbe essere davvero facile, ma per qualche motivo non riesco a trovare alcuna documentazione che mi indichi come farlo. Questa è la mia forma:

class MyForm(forms.Form): 
    charfield1 = forms.CharField(max_length=3) 
    charfield2 = forms.CharField(max_length=3) 
    choicefield = forms.ModelChoiceField(MyModel.objects.all()) 

Ho provato solo facendo:

form = MyForm() 
form.charfield1 = "foo" 
form.charfield2 = "bar" 
# a model choice field 
form.choicefield = MyModel.objects.get(id=3) 

che non funziona.

risposta

79

Prova:

form = MyForm({'charfield1': 'foo', 'charfield2': 'bar'}) 

Il costruttore di Form oggetti può prendere un dizionario di valori di campo. Ciò crea un modulo associato, che può essere utilizzato per convalidare i dati e rendere il modulo come HTML con i dati visualizzati. Vedere la documentazione the forms API per ulteriori dettagli.

Edit:

Per ragioni di completezza, se non si desidera associare il modulo e si desidera solo di dichiarare valori iniziali per alcuni campi, è possibile utilizzare il seguente comando:

form = MyForm(initial={'charfield1': 'foo', 'charfield2': 'bar'}) 

Vedere la documentazione di initial values per i dettagli.

+0

grazie - questo funziona. Tuttavia, non funziona con la chiave esterna di un modello. Ho provato a passare l'istanza del modello stessa nel dizionario, che genera un'eccezione, e ho provato a passare in pk/id, che non ha esito negativo, ma non precarica il caricamento corretto nell'interfaccia utente del mio modulo. – Cory

+0

L'utilizzo dell'id oggetto dovrebbe funzionare. L'ho appena testato con ModelChoiceField. Potresti per favore mostrarci la tua definizione di forma? –

+0

ha aggiunto la definizione del modulo nella modifica. – Cory

23

Esistono due modi per compilare un modulo Django.

Il primo è passare un dizionario come primo argomento quando lo si istanzia (o lo si passa come il kwarg data, che è la stessa cosa). Questo è quello che fai quando vuoi usare i dati POST per popolare e convalidare il modulo.

data_dict = {'charfield1': 'data1', 'charfield2': 'data2', 'choicefield': 3} 
form = MyForm(data_dict) 

Tuttavia, questo innescherà convalida sul modulo, quindi funziona solo se in realtà si sta passando a dati validi e completi per cominciare - altrimenti si iniziare con errori.

L'altro modo per compilare un modulo è utilizzare il parametro initial (documentato here). Fornisce i valori iniziali per i campi modulo, ma fa la convalida trigger non. È quindi adatto se non si inseriscono tutti i valori, ad esempio.

form = MyForm(initial=data_dict) 

per popolare un choicefield via initial, utilizzare il valore pk.

+0

In base a quanto sopra, come fornite i dati ai campi del modulo cliente? – Chris

+0

@Chris, se hai una domanda e non è coperta da quanto sopra, apri una nuova domanda e chiedila lì, con tutti i dettagli. –

+0

Era una domanda secondaria relativa a questa risposta. – Chris

12

È possibile utilizzare model_to_dict() per convertire un'istanza in un dizionario e quindi compilare un modulo con quello. Qualcosa del genere dovrebbe funzionare:

from django.forms.models import model_to_dict 
... 
my_obj = MyModel.objects.get(abc=123) 
form = MyForm(initial=model_to_dict(my_obj)) 

Nota: sto usando django versione 1.3

1

Per quello che vale, il FormView class-based view modo per farlo sarebbe quello di ignorare s' get_initial il FormView funzione.get_initial restituisce gli argomenti della parola chiave iniziale utilizzati da get_form_kwargs per creare un'istanza del modulo.

Documenti:

  • per get_initial, here,
  • per get_form_kwargs, here.

codice di esempio:

from django.views.generic.edit import FormView 

class MyFormView(FormView): 

    def get_initial(self): 
     initial = super(MyFormView, self).get_initial() 
     # update initial field defaults with custom set default values: 
     initial.update({'charfield1': 'foo', 'charfield2': 'bar'}) 
     return initial