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


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.