Django Formで動的にフィールドやMetaクラスの変数を初期化する方法

DjangoのFormを使うときにフィールドのhelp_textやwidgetのattrs、Metaクラスの変数を動的に変更したい時があります。

今回は動的にFormのフィールドやMetaクラスの変数を動的に初期化する方法を紹介します。

# フィールドのカスタマイズ方法

from django import forms

class UsernameForm(forms.Form):
 
    username = UsernameField(widget=forms.TextInput(attrs={'autofocus': True}))

    def __init__(self, *args, **kwargs):
	self.hoge = kwargs.pop('hoge', None)
        super().__init__(*args, **kwargs)

        self.fields['username'].max_length = 254
        # widgetのattrs属性を設定
        self.fields['username'].widget.attrs['maxlength'] = 254 
        self.fields['username'].label = 'ユーザ名'

各フィールドにはself.fields[‘fieldname’]でアクセスできます。

基本的には継承元の__init__メソッドを実行した後、fieldsの初期化を行います。

しかし、独自のキーワード引数を使う場合は、super().__init__(*args, **kwargs)を実行する前に、kwargsから取り出すと上手くいきます。

Metaクラスの変数のカスタマイズ方法

django.contrib.auth.formsモジュールにあるUserCreationFormクラスを解説用に使います。

from django import forms
from django.contrib.auth.models import User


class UserCreationForm(forms.ModelForm):
 
   # (中略)

    class Meta:
        model = User
        fields = ("username",)
        field_classes = {'username': UsernameField}

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Metaクラスの変数にアクセスする方法。_metaを使う
        if self._meta.model.USERNAME_FIELD in self.fields:
            self.fields[self._meta.model.USERNAME_FIELD].widget.attrs['autofocus'] = True


Metaクラスのフィールドには、self._metaでアクセスできます。

Userクラスにはusernameフィールドがあり、

USERNAME_FIELD = ‘username’

と、設定されているので__init__メソッド内のif文はTrueとなり、usernameフィールドのウィジェットのアトリビュートにautofocus=Trueが設定されます。

スポンサーリンク
スポンサーリンク