Django: изменение содержимого поля при каждом действии типа сохранения
Перед фиксацией записи в базе данных я хочу выполнить проверку на вменяемость определенного поля. Точнее, это поле ArrayField, и я хочу удалить все значения NaN/None и заменить их нулем.
Однако существует множество способов создать такую запись. Пользователь может MyObject().save()
, или MyObject.objects.create()
, или MyObject.objects.bulk_create()
, и даже MyObject.objects.bulk_update(field=my_field)
. Я полагаю, что есть также способы, которые может использовать Django Rest Framework.
Как я могу быть уверен, что NaN/None всегда заменяется на ноль перед фиксацией в базе данных? Должен ли я переписать все вышеуказанные методы? Должен ли я создать пользовательское поле, которое наследует от ArrayField
, но выполняет всю обработку данных? Какова наилучшая практика?
В итоге я последовал собственному совету и подклассифицировал DecimalField
в нечто, способное превращать NaN
в None
:
NOTE python<3.10 type-hinting syntax
import math
from typing import Any, Union
from django.db.models.fields import DecimalField
class NanToNoneDecimalField(DecimalField):
"""Converts a NaN value to None because NaN is no longer
supported for DecimalField in in Django 4.2
"""
def to_python(self, value: Union[Any, None]) -> Union[Any, None]:
try:
if math.isnan(value):
return None
except TypeError:
pass
return super().to_python(value)