** 2015 年11 月 30 日编辑:在 python 3 中,不再支持__metaclass__
模块全局变量。另外,该类已被弃用: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
我认为比在管理员中覆盖cleaned_data 更好的方法是对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 将抛出验证错误(需要字段)或创建一个不接受 NULL 的 db 列。