Zmień pole formularza Django na ukryte


128

Mam formularz Django z rozszerzeniem RegexField , który jest bardzo podobny do zwykłego pola wprowadzania tekstu.

Moim zdaniem pod pewnymi warunkami chcę to ukryć przed użytkownikiem i starać się, aby formularz był jak najbardziej podobny. Jaki jest najlepszy sposób, aby zamienić to pole w HiddenInputpole?

Wiem, że mogę ustawić atrybuty na polu za pomocą:

form['fieldname'].field.widget.attr['readonly'] = 'readonly'

I mogę ustawić żądaną wartość początkową za pomocą:

form.initial['fieldname'] = 'mydesiredvalue'

Nie zmieni to jednak formy widżetu.

Jaki jest najlepszy / najbardziej "django-y" / najmniej "hacky" sposób na uczynienie tego pola <input type="hidden">polem?

Odpowiedzi:


169

Jeśli masz niestandardowy szablon i widok, możesz wykluczyć pole i użyć, {{ modelform.instance.field }}aby uzyskać wartość.

możesz także użyć w widoku:

form.fields['field_name'].widget = forms.HiddenInput()

ale nie jestem pewien, czy będzie to chronić metodę zapisywania na poście.

Mam nadzieję, że to pomoże.


1
I w końcu z &quot;&quot; is not a valid value for a primary key.w sposobie is_valid po użyciu tego rozwiązania.
Jens Timmerman

To brzmi dziwnie. Myślę, że jest to związane z czymś innym, czy wyświetlasz jako HiddenInput klucz podstawowy obiektów, które tworzysz? Jeśli tak, nie powinieneś.
christophe31

Może to oczywiste, ale zanim to zadziała, musisz zaimportować formularze. from django import forms
teewuane

2
w wersji 1.7 użyj tej składni: hidden_field_name = forms.CharField(label='reset', max_length=256, widget=forms.HiddenInput())gdzie kluczem jest nowsza składnia widżetu na końcu. Dostosuj do swoich potrzeb.
Marc

195

Może to być również przydatne: {{ form.field.as_hidden }}


3
To najlepsza odpowiedź IMHO. Zawsze nienawidziłem używania mojego „kontrolera” kodu Pythona do określania wyświetlania pola formularza.
trpt4him

Często tworzę ogólny szablon formularzy z chrupiącymi formami. Jeśli używasz CrispyForms lub wyświetlasz pola w prostej pętli forloop, ponieważ chcesz, aby struktura formularza znajdowała się w Twojej klasie formularza, widget nadpisujący w formularzu jest dobrym sposobem na zrobienie tego. Jeśli jednak zarządzasz renderowaniem formularza w swoim szablonie, to rozwiązanie jest znacznie bardziej przejrzyste / przejrzyste.
christophe 31

Warto zauważyć, że wydaje się, że usuwa to wszystkie zajęcia, które wcześniej złożyłeś w tej dziedzinie ...
John Aaron

59

opcja, która u mnie zadziałała, zdefiniuj pole w oryginalnej formie jako:

forms.CharField(widget = forms.HiddenInput(), required = False)

wtedy gdy zastąpisz go w nowej klasie, zachowa swoje miejsce.


45

Po pierwsze, jeśli nie chcesz, aby użytkownik modyfikował dane, po prostu wykluczenie pola wydaje się czystsze. Włączenie go jako ukrytego pola po prostu dodaje więcej danych do przesłania przez sieć i zachęca złośliwego użytkownika do zmodyfikowania go, gdy tego nie chcesz. Jeśli masz dobry powód, aby dołączyć pole, ale je ukryć, możesz przekazać słowo kluczowe arg do konstruktora modelu. Może coś takiego:

class MyModelForm(forms.ModelForm):
    class Meta:
        model = MyModel
    def __init__(self, *args, **kwargs):
        from django.forms.widgets import HiddenInput
        hide_condition = kwargs.pop('hide_condition',None)
        super(MyModelForm, self).__init__(*args, **kwargs)
        if hide_condition:
            self.fields['fieldname'].widget = HiddenInput()
            # or alternately:  del self.fields['fieldname']  to remove it from the form altogether.

Zatem Twoim zdaniem:

form = MyModelForm(hide_condition=True)

Wolę takie podejście do modyfikacji wewnętrznych elementów modelu w widoku, ale to kwestia gustu.


11
po prostu prosta wskazówka, kwargs.pop ('hide_condition', False) zamiast kwargs ['hide_condition']. poradzisz sobie z przypadkiem braku argumentu, będziesz mieć wartość default i del w tym samym czasie.
christophe31

2
dzięki za cynk, christophe31. Zaktualizowałem twoją sugestię, ponieważ dzięki niej kod jest znacznie bardziej przejrzysty.
rych

1
Czy przy takim podejściu można całkowicie ukryć pole? Jak gdybyś zaczął class Meta: exclude = ["fieldname"]. Problem w tym, że podejście Meta jest „statyczne”, ale potrzebuję czegoś dynamicznego. Zobacz stackoverflow.com/questions/20243735/…
Themerius

You cab di def __init __ (self, hide_condition = True, * args, ** kwargs), czyli najczystszy sposób ...
Visgean Skeloru

22

W normalnej formie możesz to zrobić

class MyModelForm(forms.ModelForm):
    slug = forms.CharField(widget=forms.HiddenInput())

Jeśli masz wzór, możesz wykonać następujące czynności

class MyModelForm(forms.ModelForm):
    class Meta:
        model = TagStatus
        fields = ('slug', 'ext')
        widgets = {'slug': forms.HiddenInput()}

Możesz także zastąpić __init__metodę

class Myform(forms.Form):
    def __init__(self, *args, **kwargs):
        super(Myform, self).__init__(*args, **kwargs)
        self.fields['slug'].widget = forms.HiddenInput()

1

Jeśli chcesz, aby pole było zawsze ukryte, użyj:

class MyForm(forms.Form):
    hidden_input = forms.CharField(widget=forms.HiddenInput(), initial="value")

0

Możesz po prostu użyć css:

#id_fieldname, label[for="id_fieldname"] {
  position: absolute;
  display: none
}

Spowoduje to, że pole i jego etykieta staną się niewidoczne.

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.