Каков правильный способ создания установщика для поля модели, не относящегося к свойствам?

Я хочу определить функцию setter для поля модели Django, чтобы проверить ввод и немедленно вызвать ошибку, если значение недействительно.

Я не думаю, что выполнение проверки в save() или pre_save() является возможное решение моей проблемы из-за вещей, не зависящих от меня.

Кроме того, преобразование поля в свойство и использование простых field.getter и field.setter невозможны, так как это нарушит .filter(), .exclude() и т. д. в поле, а также требует изменения схемы, даже если я изменил field на _field и перебил менеджера.

Итак, я вынужден переопределить __setattr__ или есть лучший способ сделать это?


person Kimvais    schedule 28.09.2012    source источник


Ответы (3)


Смотрите этот билет django:

https://code.djangoproject.com/ticket/3148

Также смотрите здесь для обсуждения:

геттер/сеттер полей модели Django

И этот пост в блоге:

http://www.b-list.org/weblog/2006/aug/18/django-tips-using-properties-models-and-managers/

Также обратите внимание, что есть возможность использовать пользовательский менеджер, который переводит ваши filter kwargs для вас, и использовать _name для полей, и создавать свои собственные @name.setter @name.getter и т. д.

person Alex Hart    schedule 28.09.2012
comment
Вместо того, чтобы предоставлять только ссылки, было бы полезно, если бы вы резюмировали идею каждой из них в ответе. - person guival; 14.01.2019

Вы можете подклассифицировать поле и переопределить to_python.

class UnforgivingCharField(CharField):
    __metaclass__ = models.SubfieldBase

    def to_python(self, value):
        if not passes_my_test(value):
            raise Hell()
        return super(UnforgivingCharField, self).to_python(value)

Это используется, когда значение установлено, а также во время get_prep_value и т. д., поэтому при фильтрации будут обнаружены недопустимые значения.

Подробнее об этом здесь. Обратите внимание на строку в нижней части связанного раздела, которая сообщает нам, что будет вызван to_python.

Изменить: на тот случай, если вы используете Юг, вам нужно будет добавить правила самоанализа, если вы реализуете настраиваемые поля модели.

person dokkaebi    schedule 28.09.2012

Можете ли вы просто определить функцию, которая обеспечивает правильную функциональность и выдает правильную ошибку?

class YourModel(models.Model):

   def add_your_value(self, value):
       # check if value is correct
       # raise exception if it isn't
       # set correct property
person dm03514    schedule 28.09.2012
comment
Да, я могу, но это не мешает другим людям делать mymodelinstance.is_this_true_or_false = "banana" - person Kimvais; 28.09.2012