Django の CharField の max_length (min_length) の設定値 fields や base_fields で参照することで変更できますが、バリデーションや HTML で出力したときの maxlength は init 時に設定されるため変更されません。
仕様によっては定義したあとに変更したいケースも存在するのでその方法について一例を紹介します。
実装
# fields.py
from django.forms.fields import CharField
class CustomCharField(CharField):
def reset_max_length(self, max_length: int = None):
prev = self.max_length
self.max_length = max_length
v = None
if max_length:
# パラメータの max_length が設定されている場合は、新しい validator を定義する
v = validators.MaxLengthValidator(max_length)
else:
# 削除するため同じ validator を定義する
v = validators.MaxLengthValidator(prev)
self.reset_validator(validator, is_remove=not max_length)
self.reset_widget_attrs("maxlength", value=max_length)
def reset_validator(self, validator, is_remove: bool = False):
"""validatorを初期化"""
exists = False
index: int = None
for i, v in enumerate(self.validators):
# パラメータの validator と同じものの index をシュトック
if isinistance(v, type(validator)):
index = i
break
if index:
# 同じ validator が存在する場合
if is_remove:
del self.validators[index]
else:
self.validators[index] = validator
elif not is_remove:
self.validators.append(validator)
def reset_widget_attrs(self, key: str, value=None):
"""widgetの属性を初期化"""
if key in self.widget.attrs:
if value:
self.widget.attrs[key] = value
else:
del self.wiget.attrs[key]
以下のように fields の設定を変更したい箇所で呼び出すような使い方を想定しています。
# forms.py
self.fields["text"].reset_max_length(max_length=200)