66 votes

Prépopulation du formulaire Django (non-modèle)

J'essaie de pré-remplir les données dans mon formulaire django en fonction de certaines informations, mais je n'utilise PAS ModelForm, donc je ne peux pas simplement définir l'instance.

Cela devrait être très simple, mais pour une raison quelconque, je ne trouve aucune documentation m'indiquant comment procéder. Voici mon formulaire :

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 le faire :

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

ce qui ne fonctionne pas.

111voto

Ayman Hourieh Points 39435

Essayez :

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

Le constructeur de Form peuvent prendre un dictionnaire de valeurs de champs. Cela crée un formulaire lié, qui peut être utilisé pour valider les données et rendre le formulaire en HTML avec les données affichées. Voir l'API de formulaires pour plus de détails.

Edit :

Par souci d'exhaustivité, si vous ne souhaitez pas lier le formulaire et que vous voulez simplement déclarer les valeurs initiales de certains champs, vous pouvez utiliser ce qui suit :

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

Voir la documentation de valeurs initiales pour les détails.

0 votes

Merci - 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 lui-même dans le dictionnaire, qui jette une exception, et j'ai essayé de passer dans le pk/id, qui n'échoue pas, mais ne le précharge pas correctement dans mon formulaire UI.

0 votes

Utiliser l'identifiant de l'objet devrait fonctionner. Je viens de le tester avec un ModelChoiceField. Pourriez-vous nous montrer la définition de votre formulaire ?

0 votes

J'ai testé à nouveau. Ce qui suit fonctionne (2 est un id d'un objet dans le modèle) : MyForm({'charfield1' : 'foo', 'charfield2' : 'bar', 'choicefield' : '2'}). Êtes-vous sûr d'utiliser un identifiant qui existe dans la base de données ? Je ne vois rien d'autre qui puisse causer ce problème pour le moment.

31voto

Daniel Roseman Points 199743

Il existe deux façons de remplir un formulaire Django.

La première consiste à passer un dictionnaire en tant que premier argument lorsque vous l'instanciez (ou à le passer en tant qu'argument de l'attribut data kwarg, ce qui revient au même). C'est ce que vous faites lorsque vous voulez 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 le formulaire, et ne fonctionne donc que si vous transmettez des données valides et complètes pour commencer - sinon, vous commencerez à avoir des erreurs.

L'autre moyen de remplir un formulaire est d'utiliser la fonction initial (documenté ici ). Cela donne des valeurs initiales pour les champs du formulaire, mais ne pas validation du déclencheur. Il convient donc si vous ne remplissez pas toutes les valeurs, par exemple.

form = MyForm(initial=data_dict)

Pour remplir un champ de choix via initial , utilisez la valeur pk.

0 votes

Sur la base de ce qui précède, comment fournir des données aux champs du formulaire client ?

0 votes

@Chris, si vous avez une question et qu'elle n'est pas couverte par ce qui précède, veuillez ouvrir une nouvelle question et la poser là, avec tous les détails.

0 votes

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

15voto

Andrew Calder Points 143

Vous pouvez utiliser model_to_dict() pour convertir une instance en un dictionnaire, puis remplir un formulaire avec celui-ci. Quelque chose comme ceci 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 1.3 de django.

5voto

Josvic Zammit Points 4982

Pour ce que ça vaut, le FormView La façon de procéder pour une vue basée sur une classe serait de remplacer l'option FormView 's get_initial fonction. get_initial renvoie les arguments initiaux des mots-clés utilisés par get_form_kwargs pour instancier le formulaire.

Docs :

  • pour get_initial , ici ,
  • pour get_form_kwargs , ici .

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X