Ustawianie wybranej wartości w formularzach Django


107

Oto deklaracja pola w formularzu:

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

Chciałbym ustawić wartość początkową na be, 3ale to nie działa. Bawiłem się parametrami, cudzysłowami / brakiem cudzysłowów itp ... ale bez zmian.

Czy ktoś mógłby udzielić mi ostatecznej odpowiedzi, jeśli jest to możliwe? I / lub niezbędne poprawki w moim fragmencie kodu?

Używam Django 1.0


Zastanawiałem się nad tym samym. „Początkowa” wydaje się nie działać również z opcjami w najnowszej wersji trunk.
Ty.

Odpowiedzi:


115

Spróbuj ustawić wartość początkową podczas tworzenia wystąpienia formularza:

form = MyForm(initial={'max_number': '3'})

3
Czy '3'odpowiada pierwszej wartości krotki czy drugiej?
Bestasttung

4
krotki reprezentują pary (wartość, etykieta) dla opcji i chcesz określić wartość początkową - więc „3” odnosi się do pierwszego elementu.
Tom

95

Nie dotyczy to bezpośredniego pytania, ale pytanie to pojawia się w przypadku wyszukiwań związanych z próbą przypisania wybranej wartości do ChoiceField.

Jeśli wywołałeś już super().__init__swoją klasę Form, powinieneś zaktualizować form.initialsłownik, a nie field.initialwłaściwość. Jeśli studiujesz form.initial(np. print self.initialPo wezwaniu super().__init__), będzie zawierał wartości dla wszystkich pól. Posiadanie Nonew tym dyktandzie wartości spowoduje nadpisanie field.initialwartości.

na przykład

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'

3
jeśli nie rozumiesz tej odpowiedzi, przeczytaj ten formularz django gotchas
ChillarAnand

1
Nie jestem pewien, czy to dlatego, że ta odpowiedź jest tak stara, że ​​to już nie działa, ale nie mogę sprawić, by to rozwiązanie zadziałało. Próbowałem wszystkich kombinacji powyższych i nadal nie czuję miłości. Ponownie zadałem to pytanie tutaj: stackoverflow.com/questions/52191096/… Jeśli odpowiedź jest nadal taka sama, daj mi znać, co jest nie tak z moim kodem. Dziękuję Ci!
Lehrian,

48

Możesz także wykonać następujące czynności. w twojej formie class def:

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

następnie wywołując formularz w swoim widoku, możesz dynamicznie ustawić zarówno początkowe wybory, jak i listę wyboru.

yourFormInstance = YourFormClass()

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

Uwaga: początkowe wartości muszą być listą, a wybory muszą być 2-krotkami, w moim przykładzie powyżej mam listę 2-krotek. Mam nadzieję że to pomoże.


5
Może warto zauważyć, że wartość initialodnosi się do klucza wybranej pozycji, a nie do jej indeksu. Zajęło mi kilka prób, żeby to rozwiązać!
BigglesZX

20

Natknąłem się również na ten problem i zorientowałem się, że problem dotyczy przeglądarki. Po odświeżeniu przeglądarka ponownie wypełnia formularz tymi samymi wartościami, co poprzednio, ignorując zaznaczone pole. Jeśli wyświetlisz źródło, zobaczysz, że zaznaczona wartość jest poprawna. Lub umieść kursor w polu adresu URL przeglądarki i naciśnij Enter. Spowoduje to ponowne załadowanie formularza od zera.


1
po prostu fyi, to nadal się dzieje w FF6. Naciśnięcie przycisku odświeżania nie wystarczy. Ale w Google Chrome wystarczy przycisk odświeżania, nie trzeba iść do paska adresu
mhd

1
Myślę, że zawsze będzie się to działo w Firefoksie; jest to zamierzone zachowanie.
wspólny

Nadal dzieje się w Chrome 83, uratowałeś mi życie!
Lapin

7

Odpowiedzi Toma i Burtona w końcu działają dla mnie, ale miałem mały problem ze zrozumieniem, jak zastosować je do pliku ModelChoiceField.

Jedyny trick jest to, że wybory są przechowywane jako krotek (<model's ID>, <model's unicode repr>), więc jeśli chcesz, aby ustawić początkowy wybór modelu, mijamy modelu identyfikator jako wartości początkowej, a nie sam obiekt lub jego nazwę lub cokolwiek innego. Wtedy jest to tak proste, jak:

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

Alternatywnie initialargument można zignorować zamiast dodatkowego wiersza za pomocą:

form.fields['manager'].initial = manager_employee_id

1
Twoja druga linia kodu działa bezbłędnie w jednym z tych rzadkich przypadków, w których musisz ustawić początkową wartość formularza po GETżądaniu i ustawić ją z poziomu widoku.
kstratis,

3

Dave - czy masz szczęście w znalezieniu rozwiązania problemu z przeglądarką? Czy istnieje sposób na wymuszenie odświeżenia?

Jeśli chodzi o pierwotny problem, spróbuj wykonać następujące czynności podczas inicjowania formularza:

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

1
To nie wygląda ładnie. Cytat z django 1.3, forms.py:93:Instances should always modify self.fields; they should not modify self.base_fields.
Tomas Tomecek

1

Aby mieć pewność, muszę zobaczyć, jak renderujesz formularz. Wartość początkowa jest używana tylko w postaci niezwiązanej, jeśli jest powiązana, a wartość dla tego pola nie jest zawarta, nic nie zostanie wybrane.


-4

Spróbuj, to działa dla mnie, dodałem to w models.py

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

max_number = forms.ChoiceField(max_length = 2, choices = options, default ='3')

6
To daje błąd w 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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.