Django ORM:BooleanField可以关联数据库中的char列吗?
我接手了一个旧系统的数据库,这个数据库有很多问题。其中有一张表的某一列本来应该是布尔值(也就是只有真和假),结果却是一个字符型(varchar(1)),用'N'或'0'来表示假,用'Y'或'1'来表示真。代码的不同部分在写的时候用的约定不一样,但在读取的时候似乎都能识别这两种方式。
我正在把这个系统从Java重写成Python+Django,等我把这个新系统做好后,才能关闭旧系统,并“清理”数据库里的混乱。
我想在模型类中让这个字段看起来像布尔值,这样等数据库修正后,我只需要把代码中的这个字段改成普通的BooleanField就可以了。有没有简单的方法可以做到这一点?
2 个回答
3
我的情况有点类似,不过旧的数据一直用Y和N来表示真和假,但我还遇到一个问题,就是有些字段可以是空值(Null)。所以我这里有一些自定义的字段类型。我觉得这些例子更完整,能更好地展示在这种情况下你可以做些什么。而且我还继承了BooleanField类型,我觉得这样在表单中显示和编辑这些字段会更好。
from django.db import models
class YNBooleanField(models.BooleanField):
def __init__(self, *args, **kwargs):
kwargs['max_length'] = 1
super(YNBooleanField, self).__init__(*args, **kwargs)
def to_python(self, value):
if value in ('Y', 'y'):
return True
elif value in ('N', 'n'):
return False
else:
raise ValueError
def get_prep_value(self, value):
if value:
return 'Y'
else:
return 'N'
class NullYNBooleanField(models.NullBooleanField):
def __init__(self, *args, **kwargs):
kwargs['max_length'] = 1
super(NullYNBooleanField, self).__init__(*args, **kwargs)
def to_python(self, value):
if value is None:
return None
elif value in ('Y', 'y'):
return True
elif value in ('N', 'n'):
return False
else:
raise ValueError
def get_prep_value(self, value):
if value is None:
return None
elif value:
return 'Y'
else:
return 'N'
5
你可以通过创建自己的字段类来实现你想要的功能,方法是继承 django.db.models.Field,并实现 to_python 方法,比如:
from django.db import models
class MyField(models.CharField):
def to_python(self, value):
if value in ('Y', '1'):
return True
if value in ('N', '0'):
return False
raise ValueError
希望这能给你一些启发 :)