Измените поле формы Django на скрытое поле

89

У меня есть форма django с RegexField (которая очень похожа на обычное текстовое поле ввода). На мой взгляд, при определенных условиях я хочу скрыть это от пользователя и попытаться сохранить форму как можно более похоже.

Каков наилучший способ превратить это поле в поле HiddenInput? Я знаю, что я могу установить атрибуты в поле с помощью form['fieldname'].field.widget.attr['readonly'] = 'readonly', и я могу установить желаемое начальное значение с помощью form.initial['fieldname'] = 'mydesiredvalue'. Однако это не изменит вид виджета.

Какой лучший/самый django-y/наименее опасный способ сделать это поле поле <input type="hidden"?

Теги:
django-forms

5 ответов

113
Лучший ответ

Если у вас есть собственный шаблон и просмотр, вы можете исключить это поле и использовать {{ modelform.instance.field }} для получения значения.

также вы можете использовать в представлении:

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

но я не уверен, что он сохранит метод сохранения в сообщении.

Надеюсь, что это поможет.

  • 1
    Я получаю &quot;&quot; is not a valid value for a primary key. в методе is_valid после использования этого решения.
  • 0
    Это звучит странно. Я думаю, что это связано с чем-то другим, отображаете ли вы как HiddenInput первичный ключ объектов, которые вы создаете? Если да, вы не должны.
Показать ещё 2 комментария
121

Это также может быть полезно: {{ form.field.as_hidden }}

  • 2
    Это лучший ответ ИМХО. Я всегда ненавидел использовать мой «контроллерный» код Python для определения отображения поля формы.
36

Во-первых, если вы не хотите, чтобы пользователь изменял данные, то кажется, что чище просто исключить это поле. Включая его как скрытое поле, он просто добавляет больше данных для отправки по проводам и предлагает злоумышленнику изменить его, когда вы этого не хотите. Если у вас есть веская причина включить это поле, но скрыть его, вы можете передать ключевое слово arg в конструктор modelform. Что-то вроде этого возможно:

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)

Я предпочитаю этот подход для модификации внутренних элементов modelform в представлении, но это вопрос вкуса.

  • 11
    просто простой совет, kwargs.pop ('hide_condition', False) вместо kwargs ['hide_condition']. Вы будете обрабатывать случай без аргументов, иметь значение по умолчанию и значение del одновременно.
  • 2
    спасибо за совет, Кристоф31. Я обновил ваше предложение, так как оно делает код намного понятнее.
Показать ещё 2 комментария
23

параметр, который работал у меня, определяет поле в исходной форме как:

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

тогда, когда вы переопределите его в новом классе, он сохранит его.

2

Для нормальной формы вы можете сделать

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()

Ещё вопросы

Сообщество Overcoder
Наверх
Меню