1. ホーム
  2. django

[解決済み] Django のフォームで、あるフィールドを編集できないように readonly (または disabled) にするにはどうしたらいいですか?

2022-03-19 04:19:02

質問

Django のフォームで、フィールドを読み取り専用 (または無効) にするにはどうしたらいいですか?

しかし、レコードが更新モードになっているときは、いくつかのフィールドを読み取り専用にする必要があります。

例えば、新規に Item モデルでは、すべてのフィールドが編集可能でなければなりませんが、レコードを更新する際に sku フィールドを表示させ、編集できないようにすることはできますか?

class Item(models.Model):
    sku = models.CharField(max_length=50)
    description = models.CharField(max_length=200)
    added_by = models.ForeignKey(User)


class ItemForm(ModelForm):
    class Meta:
        model = Item
        exclude = ('added_by')

def new_item_view(request):
    if request.method == 'POST':
        form = ItemForm(request.POST)
        # Validate and save
    else:
            form = ItemForm()
    # Render the view

Canクラス ItemForm は再利用できますか?この場合 ItemForm または Item モデルクラス?別のクラス、"を書く必要があるでしょうか。 ItemUpdateForm "、アイテムの更新のために?

def update_item_view(request):
    if request.method == 'POST':
        form = ItemUpdateForm(request.POST)
        # Validate and save
    else:
        form = ItemUpdateForm()

解決方法は?

で指摘されているように この回答 Django 1.9では フィールド.disabled 属性があります。

disabled ブーリアン引数を True に設定すると、disabled HTML 属性を使用してフォーム・フィールドを無効にし、ユーザーによる編集を不可能にします。ユーザーがサーバーに送信するフィールドの値を変更したとしても、それは無視され、フォームの初期データの値が優先されます。

Django 1.8 以前のバージョンでは、ウィジェットでの入力を無効にして悪意のある POST ハックを防ぐために、入力のスクラブを行う必要があります。 readonly 属性を設定します。

class ItemForm(ModelForm):
    def __init__(self, *args, **kwargs):
        super(ItemForm, self).__init__(*args, **kwargs)
        instance = getattr(self, 'instance', None)
        if instance and instance.pk:
            self.fields['sku'].widget.attrs['readonly'] = True

    def clean_sku(self):
        instance = getattr(self, 'instance', None)
        if instance and instance.pk:
            return instance.sku
        else:
            return self.cleaned_data['sku']

または、次のように置き換えます。 if instance and instance.pk を、編集中であることを示す別の条件に置き換えてください。 また、属性 disabled の代わりに入力フィールドに readonly .

clean_sku 関数は readonly の値で上書きされることはありません。 POST .

そうでなければ、バインドされた入力データを拒否しながら値をレンダリングする Django の組み込みフォームフィールドは存在しません。 もしこれを望むのであれば、代わりに別の ModelForm で、編集不可能なフィールドを除外し、テンプレートの中でそれらを表示するだけです。