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, которые будут созданы после этого.

Вернуться на верх