Configurando o valor selecionado em um formulário Django.ChoiceField

106

Aqui está a declaração do campo em um formulário:

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

Gostaria de definir o valor inicial como 3e isso não parece funcionar. Eu brinquei com o parâmetro, aspas / sem aspas, etc ... mas nenhuma mudança.

Alguém poderia me dar uma resposta definitiva se for possível? E / ou o ajuste necessário no meu trecho de código?

Estou usando Django 1.0

thebiglife
fonte
Eu estive me perguntando a mesma coisa. "inicial" também não parece funcionar com as opções da última versão do porta-malas.
Ty.

Respostas:

114

Tente definir o valor inicial ao instanciar o formulário:

form = MyForm(initial={'max_number': '3'})
Tom
fonte
3
É '3'correspondente ao primeiro valor da tupla ou o segundo?
Bestasttung
4
as tuplas representam (valor, rótulo) pares para as opções e você deseja especificar o valor inicial - portanto, o '3' se refere ao primeiro item.
Tom,
95

Isso não toca na questão imediata em questão, mas esta pergunta / resposta surge para pesquisas relacionadas à tentativa de atribuir o valor selecionado a a ChoiceField.

Se você já chamou super().__init__sua classe Form, deve atualizar o form.initialdicionário, não a field.initialpropriedade. Se você estudar form.initial(por exemplo, print self.initialapós a chamada para super().__init__), ele conterá valores para todos os campos. Ter um valor de Nonenaquele dict substituirá o field.initialvalor.

por exemplo

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
fonte
3
se você não entendeu esta resposta, leia este formulário de django
pegadinhas
1
Não tenho certeza se é porque essa resposta é tão antiga que isso não funciona mais, mas não consigo fazer essa solução funcionar. Eu tentei todas as combinações acima e ainda não recebo nenhum amor. Eu fiz esta pergunta novamente aqui: stackoverflow.com/questions/52191096/… Se a resposta ainda for a mesma, por favor, me diga o que há de errado com meu código. Obrigado!
Lehrian
48

Você também pode fazer o seguinte. em sua classe de formulário def:

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

então, ao chamar o formulário em sua visualização, você pode definir dinamicamente as opções iniciais e a lista de opções.

yourFormInstance = YourFormClass()

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

Nota: os valores iniciais devem ser uma lista e as opções devem ser 2 tuplas, no meu exemplo acima eu tenho uma lista de 2 tuplas. Espero que isto ajude.

Burton Williams
fonte
5
Talvez seja importante notar que o valor de initialrefere-se à chave do item a ser selecionado, não ao seu índice. Levei algumas tentativas para resolver isso!
BigglesZX
20

Também encontrei esse problema e descobri que o problema está no navegador. Quando você atualiza o navegador está preenchendo novamente o formulário com os mesmos valores de antes, ignorando o campo marcado. Se você visualizar a fonte, verá que o valor verificado está correto. Ou coloque o cursor no campo URL do seu navegador e pressione Enter. Isso irá recarregar o formulário do zero.

Dave
fonte
1
apenas fyi, isso ainda acontece no FF6. Pressionar o botão de atualização não é suficiente. Mas no Google Chrome o botão de atualização é o suficiente, não há necessidade de ir para a barra de endereço
mhd
1
Acho que sempre acontecerá no Firefox; é o comportamento pretendido.
thepeer de
Ainda acontece no Chrome 83, você salvou minha vida cara!
lapin
7

As respostas de Tom e Burton funcionam para mim eventualmente, mas eu tive um pouco de dificuldade para descobrir como aplicá-las a um ModelChoiceField.

O único truque é que as escolhas são armazenadas como tuplas de (<model's ID>, <model's unicode repr>), então se você quiser definir a seleção inicial do modelo, você passa o ID do modelo como o valor inicial, não o objeto em si ou seu nome ou qualquer outra coisa. Então é tão simples como:

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

Alternativamente, o initialargumento pode ser ignorado no lugar de uma linha extra com:

form.fields['manager'].initial = manager_employee_id
orlade
fonte
1
Sua segunda linha de código funciona perfeitamente em um daqueles raros casos em que você precisa definir o valor inicial de um formulário após uma GETsolicitação e defini-lo de dentro de uma visualização.
kstratis
3

Dave - alguma sorte em encontrar uma solução para o problema do navegador? Existe uma maneira de forçar uma atualização?

Quanto ao problema original, tente o seguinte ao inicializar o formulário:

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

fonte
1
Isso não parece bem. Citado de django 1.3, forms.py:93:Instances should always modify self.fields; they should not modify self.base_fields.
Tomas Tomecek
1

Para ter certeza, preciso ver como você está renderizando o formulário. O valor inicial só é usado de forma desvinculada, se for vinculado e um valor para aquele campo não for incluído, nada será selecionado.

Andrew Wilkinson
fonte
-4

Experimente isso funciona para mim, eu adicionei isso em models.py

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

max_number = forms.ChoiceField(max_length = 2, choices = options, default ='3')
abhijeetmote
fonte
6
Isso dá um erro no 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