Définition de la valeur sélectionnée sur un formulaire Django.

107

Voici la déclaration du champ dans un formulaire:

max_number = forms.ChoiceField(widget = forms.Select(), 
    choices = ([('1','1'), ('2','2'),('3','3'), ]), initial='3', required = True,)

Je souhaite que la valeur initiale soit 3 et cela ne semble pas fonctionner. J'ai joué avec le paramètre, les guillemets / pas de guillemets, etc ... mais aucun changement.

Quelqu'un pourrait-il me donner une réponse définitive si c'est possible? Et / ou l'ajustement nécessaire dans mon extrait de code?

J'utilise Django 1.0

thebiglife
la source
Je me suis demandé la même chose. "initial" ne fonctionne pas non plus avec les choix de la dernière version du coffre.
Ty.

Réponses:

115

Essayez de définir la valeur initiale lorsque vous instanciez le formulaire:

form = MyForm(initial={'max_number': '3'})
À M
la source
3
Est -ce qui '3'correspond à la première valeur du tuple ou la deuxième?
Bestasttung
4
les tuples représentent des paires (valeur, étiquette) pour les options et vous voulez spécifier la valeur initiale - donc le «3» fait référence au premier élément.
Tom
95

Cela ne touche pas à la question immédiate à portée de main, mais ce Q / R apparaît pour les recherches liées à la tentative d'attribution de la valeur sélectionnée à a ChoiceField.

Si vous avez déjà appelé super().__init__votre classe Form, vous devez mettre à jour le form.initialdictionnaire, pas la field.initialpropriété. Si vous étudiez form.initial(par exemple print self.initialaprès l'appel à super().__init__), il contiendra des valeurs pour tous les champs. Avoir une valeur de Nonedans ce dict remplacera lefield.initial valeur.

par exemple

class MyForm(forms.Form):
    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        # assign a (computed, I assume) default value to the choice field
        self.initial['choices_field_name'] = 'default value'
        # you should NOT do this:
        self.fields['choices_field_name'].initial = 'default value'
colinta
la source
3
si vous ne comprenez pas cette réponse, lisez ce formulaire django
gotchas
1
Je ne sais pas si c'est parce que cette réponse est si ancienne que cela ne fonctionne plus, mais je suis incapable de faire fonctionner cette solution. J'ai essayé toutes les combinaisons de ce qui précède et je n'ai toujours pas d'amour. J'ai de nouveau posé cette question ici: stackoverflow.com/questions/52191096/... Si la réponse est toujours la même, merci de me faire savoir ce qui ne va pas avec mon code. Je vous remercie!
Lehrian
48

Vous pouvez également effectuer les opérations suivantes. dans votre classe de formulaire def:

max_number = forms.ChoiceField(widget = forms.Select(), 
                 choices = ([('1','1'), ('2','2'),('3','3'), ]), initial='3', required = True,)

Ensuite, lorsque vous appelez le formulaire dans votre vue, vous pouvez définir dynamiquement les choix initiaux et la liste de choix.

yourFormInstance = YourFormClass()

yourFormInstance.fields['max_number'].choices = [(1,1),(2,2),(3,3)]
yourFormInstance.fields['max_number'].initial = [1]

Remarque: les valeurs initiales doivent être une liste et les choix doivent être de 2 tuples, dans mon exemple ci-dessus, j'ai une liste de 2 tuples. J'espère que cela t'aides.

Burton Williams
la source
5
Il convient peut-être de noter que la valeur de initialfait référence à la clé de l'élément à sélectionner, et non à son index. Il m'a fallu quelques essais pour résoudre ce problème!
BigglesZX
20

J'ai également rencontré ce problème et j'ai découvert que le problème était dans le navigateur. Lorsque vous actualisez, le navigateur remplit à nouveau le formulaire avec les mêmes valeurs qu'auparavant, en ignorant le champ coché. Si vous affichez la source, vous verrez que la valeur cochée est correcte. Ou placez votre curseur dans le champ URL de votre navigateur et appuyez sur Entrée. Cela rechargera le formulaire à partir de zéro.

Dave
la source
1
juste pour info, cela se produit encore dans FF6. Il ne suffit pas d'appuyer sur le bouton d'actualisation. Mais dans Google Chrome, le bouton d'actualisation suffit, pas besoin d'aller à la barre d'adresse
mhd
1
Je pense que cela se produira toujours dans Firefox; c'est un comportement intentionnel.
thepeer
Cela se passe toujours dans Chrome 83, vous m'avez sauvé la vie!
lapin le
7

Les réponses de Tom et Burton fonctionnent finalement pour moi, mais j'ai eu un peu de mal à comprendre comment les appliquer à un fichier ModelChoiceField.

Le seul truc pour cela est que les choix sont stockés sous forme de tuples de (<model's ID>, <model's unicode repr>), donc si vous voulez définir la sélection initiale du modèle, vous passez l' ID du modèle comme valeur initiale, pas l'objet lui-même ou son nom ou autre chose. Ensuite, c'est aussi simple que:

form = EmployeeForm(initial={'manager': manager_employee_id})

Alternativement, l' initialargument peut être ignoré à la place d'une ligne supplémentaire avec:

form.fields['manager'].initial = manager_employee_id
Orlade
la source
1
Votre deuxième ligne de code fonctionne parfaitement dans l'un de ces rares cas où vous devez définir la valeur initiale d'un formulaire après une GETdemande et la définir à partir d'une vue.
kstratis
3

Dave - une chance pour trouver une solution au problème du navigateur? Existe-t-il un moyen de forcer un rafraîchissement?

En ce qui concerne le problème d'origine, essayez ce qui suit lors de l'initialisation du formulaire:

def __init__(self, *args, **kwargs):
  super(MyForm, self).__init__(*args, **kwargs)   
  self.base_fields['MyChoiceField'].initial = initial_value

la source
1
Cela n'a pas l'air très bien. Cité de django 1.3, forms.py:93:Instances should always modify self.fields; they should not modify self.base_fields.
Tomas Tomecek
1

Pour être sûr, j'ai besoin de voir comment vous affichez le formulaire. La valeur initiale n'est utilisée que sous une forme non liée, si elle est liée et qu'une valeur pour ce champ n'est pas incluse, rien ne sera sélectionné.

Andrew Wilkinson
la source
-4

Essayez ceci, cela fonctionne pour moi, j'ai ajouté ceci dans models.py

options = (
    ('1','1'),
    ('2','2'),
    ('3','3')
)

max_number = forms.ChoiceField(max_length = 2, choices = options, default ='3')
abhijeetmote
la source
6
Cela donne une erreur dans django 1.8.1: TypeError at /my/url/ __init__() got an unexpected keyword argument 'default' Request Method: GET Request URL: http://localhost:8000/my/url/ Django Version: 1.8.1 Exception Type: TypeError Exception Value: __init__() got an unexpected keyword argument 'default'
juliocesar