Djangoフォームフィールドを非表示フィールドに変更する


128

私は、RegexField通常のテキスト入力フィールドと非常によく似ている、を使ったDjangoフォームを持っています。

私の見解では、特定の条件下では、ユーザーに対してフォームを非表示にし、フォームをできるだけ類似させたいと考えています。このフィールドをフィールドに変える最良の方法は何HiddenInputですか?

私はフィールドに属性を設定できることを知っています:

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

そして、私は希望する初期値を次のように設定できます:

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

ただし、ウィジェットのフォームは変更されません。

このフィールドをフィールドにするための最良の/最も「django-y」/最も「ハッキー」な方法は<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メソッドでaが発生します。
Jens Timmerman、2014年

奇妙に聞こえます。私はそれが何かに関連していると思います、あなたはHiddenInputとして作成しているオブジェクトの主キーを表示していますか?はいの場合は、すべきではありません。
christophe31

おそらくこれは言うまでもありませんが、これが機能する前にフォームをインポートする必要があります。 from django import forms
teewuane 14

2
1.7では、次の構文を使用します。 hidden_field_name = forms.CharField(label='reset', max_length=256, widget=forms.HiddenInput())ここで、キーは最後の新しいウィジェット構文です。必要に応じて調整してください。
Marc

195

これも役に立つかもしれません: {{ form.field.as_hidden }}


3
これが私にとって最良の答えです。「コントローラー」のPythonコードを使用してフォームフィールドの表示を決定することは常に嫌いでした。
trpt4him

私はよくクリスピーフォームを使用して汎用フォームテンプレートを作成します。crispyformsを使用する場合、またはフォームクラスでフォーム構造を必要とするために単純なforloopでフィールドを表示する場合は、フォームでウィジェットをオーバーライドすることをお勧めします。テンプレートへのフォームのレンダリングを管理すれば、確かに、このソリューションははるかに明確/クリーンになります。
christophe31

これにより、事前にフィールドに適用したクラスがすべて消去されるように見えることに注意してください...
John Aaron

59

私にとってうまくいったオプション、元のフォームのフィールドを次のように定義します:

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

その後、新しいクラスでオーバーライドすると、その場所が保持されます。


45

まず、ユーザーにデータを変更させたくない場合は、単にフィールドを除外するほうがきれいに見えます。これを非表示フィールドとして含めると、ネットワーク経由で送信するデータが追加され、悪意のあるユーザーが望まないときにデータを変更するように招待されます。フィールドを含めて非表示にする十分な理由がある場合は、キーワード引数をモデルフォームのコンストラクターに渡すことができます。このような何か:

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 ['hide_condition']の代わりにkwargs.pop( 'hide_condition'、False)。引数なしの場合を処理し、デフォルトとdelを同時に使用します。
christophe31

2
先端をありがとう、クリストフ31。コードをより明確にするため、あなたの提案を反映して更新しました。
rych

1
このアプローチでフィールドを完全に隠すことは可能ですか?のように設定しclass Meta: exclude = ["fieldname"]ます。ここでの問題は、メタアプローチが「静的」であるということですが、動的なものが必要です。stackoverflow.com/questions/20243735/…を
Themerius

あなたはcab di def __init __(self、hide_condition = True、* args、** kwargs)これが最もきれいな方法です...
Visgean Skeloru 2015年

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
}

これにより、フィールドとそのラベルが非表示になります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.