2009-06-01 7 views
44

J'essaie de préremplir les données dans mon formulaire django en fonction de certaines informations, mais PAS en utilisant ModelForm, donc je ne peux pas simplement définir l'instance.Prépopulation de Django (non-modèle) Formulaire

Cela semble être très facile, mais pour une raison quelconque, je ne trouve aucune documentation me disant comment faire. Ceci est ma forme:

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

J'ai essayé de faire juste:

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

qui ne fonctionne pas.

Répondre

79

Essayez:

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

Le constructeur de Form objets peut prendre un dictionnaire des valeurs de champ. Cela crée un formulaire lié, qui peut être utilisé pour valider les données et rendre le formulaire au format HTML avec les données affichées. Voir la documentation the forms API pour plus de détails.

Edit:

Par souci d'exhaustivité, si vous ne voulez pas lier la forme, et vous voulez juste de déclarer les valeurs initiales pour certains champs, vous pouvez utiliser les éléments suivants à la place:

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

Voir la documentation de initial values pour plus de détails.

+0

grâce - cela fonctionne. Cependant, cela ne fonctionne pas avec la clé étrangère d'un modèle. J'ai essayé de passer dans l'instance du modèle elle-même dans le dictionnaire, ce qui lance une exception, et j'ai essayé de passer dans le pk/id, ce qui n'échoue pas, mais ne le précharge pas correctement dans mon interface utilisateur. – Cory

+0

L'utilisation de l'ID d'objet devrait fonctionner. Je viens de le tester avec un ModelChoiceField. Pourriez-vous nous montrer votre définition de formulaire? –

+0

a ajouté la définition de formulaire dans l'édition. – Cory

23

Il existe deux façons de remplir un formulaire Django. Le premier consiste à passer un dictionnaire comme premier argument lorsque vous l'instanciez (ou passez-le comme data kwarg, ce qui est la même chose). C'est ce que vous faites lorsque vous souhaitez utiliser les données POST pour remplir et valider le formulaire.

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

Cependant, cela déclenchera validation sur la forme, donc ne fonctionne que si vous passez réellement des données valides et complètes pour commencer - sinon vous partirez avec des erreurs.

L'autre manière de remplir un formulaire consiste à utiliser le paramètre initial (documenté here). Cela donne des valeurs initiales pour les champs de formulaire, mais pas de validation de déclencheur. C'est donc approprié si vous ne remplissez pas toutes les valeurs, par exemple.

form = MyForm(initial=data_dict) 

Pour alimenter un choicefield via initial, utilisez la valeur pk. Vous pouvez utiliser model_to_dict() pour convertir une instance en dictionnaire, puis remplir un formulaire avec celui-ci.

+0

Basé sur ce qui précède comment fournissez-vous des données aux champs de forme de client? – Chris

+0

@Chris, si vous avez une question et qu'il n'est pas couvert par ce qui précède, s'il vous plaît ouvrir une nouvelle question et posez-là, avec tous les détails. –

+0

C'était une question secondaire liée à cette réponse. – Chris

12

Quelque chose comme cela devrait fonctionner:

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

Note: J'utilise la version django 1.3

1

Pour ce que ça vaut, comme vue basée sur la classe FormView à faire serait de passer outre get_initial du FormView fonction.get_initial renvoie les arguments de mot clé initiaux utilisés par get_form_kwargs pour instancier le formulaire.

Docs:

  • pour get_initial, here,
  • pour get_form_kwargs, here.

Exemple de code:

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 
Questions connexes