ModelForm с полем, зависящим от прав пользователя?
У меня есть модель Address
с полем и моделью ModelForm.
class Address(Model):
number = PositiveSmallIntegerField(default=1)
class AddressForm(ModelForm):
class Meta:
model = Address
fields = "__all__"
Как добавить к ней валидатор, когда форма показывается пользователю с определенным разрешением? Форма должна вести себя так, как если бы в самой модели было числовое поле, например, так:
number = PositiveSmallIntegerField(default=1, validators=[MaxValueValidator(100)])
Под этим я подразумеваю, что форма должна допускать только значения от 0 до 100, а бэкэнд должен подтверждать, что значение находится между 0 и 100.
Представление может передать, использовать или нет ограниченное поле, следующим образом:
form = AddressForm(enable_limit=True)
А я могу сделать что-то вроде этого:
class AddressForm(ModelForm):
class Meta:
model = Address
fields = "__all__"
def __init__(self, *args, enable_limit=False, **kwargs):
if enable_limit:
self.base_fields["number"].widget.attrs["max"] = 100
Однако это только обновляет виджет. Форма жалуется на значения > 100, но это только валидация HTML-формы на стороне клиента, и, изменяя значение в запросе, я могу обойти это, что не то, чего я хочу.
По сути, я хочу указать ModelForm использовать поле Adresse.number
в качестве основы, но с дополнительным полем MaxValueValidator(100)
.
Как бы вы решили эту проблему?
Вы также можете добавить это в качестве валидатора:
from django.core.validators import MaxValueValidator
class AddressForm(ModelForm):
class Meta:
model = Address
fields = '__all__'
def __init__(self, *args, enable_limit=False, **kwargs):
super().__init__(*args, **kwargs)
if enable_limit:
self.fields['number'].validators.append(MaxValueValidator(100))
self.fields['number'].widget.attrs['max'] = 100
Я бы не работал с .base_fields
[Django-doc], поскольку это меняет "родителя", который охватывает все реальные поля этой формы. Это означает, что если в определенный момент вы используете enable_limit
, то с этого момента валидатор будет добавлен ко всем AddressForm
, которые будут созданы после этого.