** редагувати 30.11.2015 : У python 3 модульна глобальна __metaclass__змінна більше не підтримується . Additionaly, станом Django 1.10на SubfieldBaseклас був застарілим :
django.db.models.fields.subclassing.SubfieldBaseзастаріла і буде видалена в Django 1.10. Історично він використовувався для обробки полів, де потрібна конверсія типів під час завантаження з бази даних, але вона не використовувалася у .values()викликах або в агрегатах. Він був замінений на from_db_value().
Зауважте, що новий підхід не називає to_python()метод при призначенні, як це було у випадку SubfieldBase.
Тому, як це запропоновано в from_db_value() документації та в цьому прикладі , це рішення потрібно змінити на:
class CharNullField(models.CharField):
"""
Subclass of the CharField that allows empty strings to be stored as NULL.
"""
description = "CharField that stores NULL but returns ''."
def from_db_value(self, value, expression, connection, contex):
"""
Gets value right out of the db and changes it if its ``None``.
"""
if value is None:
return ''
else:
return value
def to_python(self, value):
"""
Gets value right out of the db or an instance, and changes it if its ``None``.
"""
if isinstance(value, models.CharField):
# If an instance, just return the instance.
return value
if value is None:
# If db has NULL, convert it to ''.
return ''
# Otherwise, just return the value.
return value
def get_prep_value(self, value):
"""
Catches value right before sending to db.
"""
if value == '':
# If Django tries to save an empty string, send the db None (NULL).
return None
else:
# Otherwise, just pass the value.
return value
Я думаю, що кращим способом, ніж перевизначення очищених_даних в адміністраторі, було б підкласинг charfield - таким чином, незалежно від того, яка форма звертається до поля, вона буде "просто працювати". Ви можете зловити ''безпосередньо перед тим, як вона буде відправлена в базу даних, і вилучити NULL відразу після того, як вона вийде з бази даних, а решта Django не дізнається / не піклується. Швидкий і брудний приклад:
from django.db import models
class CharNullField(models.CharField): # subclass the CharField
description = "CharField that stores NULL but returns ''"
__metaclass__ = models.SubfieldBase # this ensures to_python will be called
def to_python(self, value):
# this is the value right out of the db, or an instance
# if an instance, just return the instance
if isinstance(value, models.CharField):
return value
if value is None: # if the db has a NULL (None in Python)
return '' # convert it into an empty string
else:
return value # otherwise, just return the value
def get_prep_value(self, value): # catches value right before sending to db
if value == '':
# if Django tries to save an empty string, send the db None (NULL)
return None
else:
# otherwise, just pass the value
return value
Для свого проекту я завантажив це у extras.pyфайл, який живе в корені мого сайту, тоді я можу просто from mysite.extras import CharNullFieldу програмі свого додаткаmodels.py файл . Поле діє так само, як CharField - просто не забудьте встановити blank=True, null=Trueпри оголошенні поля, інакше Django видасть помилку перевірки (потрібне поле) або створить колонку db, яка не приймає NULL.
def get_db_prep_value(self, value, connection, prepared=False)як метод виклику. Перевірте groups.google.com/d/msg/django-users/Z_AXgg2GCqs/zKEsfu33OZMJ для отримання додаткової інформації. Наступний метод працює і для мене: def get_prep_value (self, value): if value == "": #if Django намагається зберегти рядок '', надіслати db None (NULL) return Ніщо інше: return value #otherwise, just передайте значення