Змініть поле форми Джанго на приховане


128

У мене форма Django з a RegexField, яка дуже схожа на звичайне поле для введення тексту.

На мою думку, за певних умов я хочу приховати його від користувача та намагаюся зберегти форму максимально схожою. Який найкращий спосіб перетворити це поле на HiddenInputполе?

Я знаю, що я можу встановлювати атрибути на полі за допомогою:

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

І я можу встановити бажане початкове значення за допомогою:

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

Однак це не змінить форму віджета.

Який найкращий / найбільш "джанго-у" / найменш "хакітний" спосіб зробити це поле <input type="hidden">полем?

Відповіді:


169

Якщо у вас є власний шаблон і перегляд, ви можете виключити поле і використовувати {{ modelform.instance.field }}для отримання значення.

також ви можете скористатися переглядом:

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

але я не впевнений, що це захистить метод збереження на пошті.

Сподіваюся, це допомагає.


1
&quot;&quot; is not a valid value for a primary key.Після використання цього рішення я закінчую метод is_valid.
Йенс Тіммерман

Це звучить дивно. Я думаю, що це пов’язано з чимось іншим, чи відображаєте ви як HiddenInput первинний ключ об’єктів, які ви створюєте? Якщо так, то не слід.
christophe31

Можливо, це само собою зрозуміло, але вам потрібно імпортувати форми, перш ніж це спрацює. from django import forms
teewuane

2
на 1.7 використовуйте цей синтаксис: hidden_field_name = forms.CharField(label='reset', max_length=256, widget=forms.HiddenInput())де ключовим є новіший синтаксис віджетів на кінці. Налаштуйте свої потреби.
Марк

195

Це також може бути корисно: {{ form.field.as_hidden }}


3
Це найкраща відповідь ІМХО. Я завжди ненавиджу, щоб мій "контролер" Python код визначав відображення поля форми.
trpt4him

Я часто роблю загальний шаблон форми з хрусткою формою. Якщо ви використовуєте crispyforms або ви відображаєте поля у простому forloop, оскільки ви хочете, щоб ваша форма форми була у вашому класі форм, то віджет, який перевизначає форму, є хорошим способом це зробити. Але якщо ви керуєте візуалізацією форми у своєму шаблоні, справді це рішення набагато чіткіше / чіткіше.
christophe31

Варто зазначити, що це, здається, видаляє всі класи, які ви заздалегідь застосували до цього поля ...
Джон Аарон

59

варіант, який працював для мене, визначте поле в оригінальній формі як:

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

тоді, коли ви перекриєте його в новому класі, він збереже його місце.


45

По-перше, якщо ви не хочете, щоб користувач міняв дані, тоді видається поле більш простим виключити поле. Якщо включити його як приховане поле, просто додається більше даних для надсилання через провід і запрошує зловмисного користувача змінити його, коли ви цього не хочете. Якщо у вас є вагомі підстави включити поле, але приховати його, ви можете передати ключове слово arg конструктору моделі. Можливо, щось подібне:

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.

Тоді на ваш погляд:

form = MyModelForm(hide_condition=True)

Я віддаю перевагу такому підходу до модифікації внутрішнього вигляду моделі на погляд, але це питання смаку.


11
просто простий підказок, kwargs.pop ('hid_condition', False) замість kwargs ['hid_condition']. Ви будете працювати з випадком no arg, матимете за замовчуванням і del одночасно.
christophe31

2
дякую за пораду, Христофо31. Я оновив вашу пропозицію, оскільки це робить код набагато зрозумілішим.
рич

1
Чи можна повністю заховати поле таким підходом? Як якщо б ви ввійшли class Meta: exclude = ["fieldname"]. Проблема тут полягає в тому, що мета-підхід "статичний", але мені потрібно щось динамічне. Див stackoverflow.com/questions/20243735 / ...
Themerius

Ви так, щоб це було найчистішим способом ...
Visgean Skeloru

22

Для нормальної форми можна зробити

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

Якщо у вас є модель форми, ви можете зробити наступне

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

Ви також можете змінити __init__метод

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

1

Якщо ви хочете, щоб поле завжди було прихованим, використовуйте наступне:

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

0

Ви можете просто використовувати css:

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

Це зробить поле та його мітку невидимими.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.