Повышение ValidationError в методе to_python () пользовательского поля нарушает формы администратора - PullRequest
2 голосов
/ 17 января 2012

У меня есть настраиваемое поле с именем CustomField, чтобы обернуть класс с именем Example примерно так:

from django import forms
from django.db import models
from . import Example

class CustomField(models.CharField):
    __metaclass__ = models.SubfieldBase

    def to_python(self, value):
        try:
            return Example(value)
        except Example.InvalidValueException:
            raise forms.ValidationError('bad value!')

    def get_prep_value(self, value):
        return unicode(value)

    def formfield(self, **kwargs):
        defaults = {'form_class': forms.CharField}
        defaults.update(kwargs)
        return super(CustomField, self).formfield(**defaults)

Проблема в формах администратора: когда ValidationError вызывается в clean()или validate() методов для поля, сообщение об ошибке отображается аккуратно рядом с соответствующим полем ввода в форме.Тем не менее, когда он вызывается в методе to_python(), как в моем настраиваемом поле, недопустимое значение некорректно разрывает форму и отображает страницу ошибки с обратной трассировкой около ValidationError.Как заставить мое поле корректно работать с формами администратора Django?

РЕДАКТИРОВАТЬ: Основываясь на предложении ниже, я попытался:

class CustomFieldForm(forms.CharField):
    def validate(self, value):
        raise forms.ValidationError('test')

И изменил метод formfield(), чтобы использоватьКласс выглядит так:

    def formfield(self, **kwargs):
        defaults = {'form_class': CustomFieldForm}
        defaults.update(kwargs)
        return super(CustomField, self).formfield(**defaults)

Тем не менее, метод to_python() по-прежнему вызывается до того, как метод CustomFieldForm.validate() и Example.InvalidValueException, вызванные в предыдущем методе в случае недопустимого значения, нарушают форму администратора.

Ответы [ 2 ]

4 голосов
/ 17 января 2012

Я нашел решение благодаря ojii, указывающему мне правильное направление. Объяснение в документах о SubfieldBase. Короче говоря, поскольку я использовал __metaclass__ = models.SubfieldBase, мне нужно было создать подкласс forms.CharField и поднять ValidationError из метода to_python(), а затем использовать его в методе formfield() моего поля вместо простого forms.CharField.

0 голосов
/ 17 января 2012

Вы не должны поднимать forms.ValidationError в поле модель . Скорее, в классе поля, возвращенном в formfield, реализуйте метод validate, который принимает параметр value. Этот метод может вызвать ошибки проверки формы.

...