Python Django:自定义模型字段在表单中未显示正确的值
我需要在多数据类型的关系数据库中存储任意数据,因此我提出了一个解决方案,除了存储数据本身,还存储数据的数据类型(str、int等)。这允许在检索时将存储在数据库中的字符串转换为数据的任何适当数据类型。为了存储数据类型,我创建了一个自定义模型字段:Python Django:自定义模型字段在表单中未显示正确的值,python,django,django-forms,django-models,Python,Django,Django Forms,Django Models,我需要在多数据类型的关系数据库中存储任意数据,因此我提出了一个解决方案,除了存储数据本身,还存储数据的数据类型(str、int等)。这允许在检索时将存储在数据库中的字符串转换为数据的任何适当数据类型。为了存储数据类型,我创建了一个自定义模型字段: class DataType(object): SUPPORTED_TYPES = { u'unicode': unicode, u'str': str, u'bool': bool,
class DataType(object):
SUPPORTED_TYPES = {
u'unicode': unicode,
u'str': str,
u'bool': bool,
u'int': int,
u'float': float
}
INVERSE_SUPPORTED_TYPES = dict(zip(SUPPORTED_TYPES.values(), SUPPORTED_TYPES.keys()))
TYPE_CHOICES = dict(zip(SUPPORTED_TYPES.keys(), SUPPORTED_TYPES.keys()))
def __init__(self, datatype=None):
if not datatype:
datatype = unicode
t_datatype = type(datatype)
if t_datatype in [str, unicode]:
self.datatype = self.SUPPORTED_TYPES[datatype]
elif t_datatype is type and datatype in self.INVERSE_SUPPORTED_TYPES.keys():
self.datatype = datatype
elif t_datatype is DataType:
self.datatype = datatype.datatype
else:
raise TypeError('Unsupported %s' % str(t_datatype))
def __unicode__(self):
return self.INVERSE_SUPPORTED_TYPES[self.datatype]
def __str__(self):
return str(self.__unicode__())
def __len__(self):
return len(self.__unicode__())
def __call__(self, *args, **kwargs):
return self.datatype(*args, **kwargs)
class DataTypeField(models.CharField):
__metaclass__ = models.SubfieldBase
description = 'Field for storing python data-types in db with capability to get python the data-type back'
def __init__(self, **kwargs):
defaults = {}
overwrites = {
'max_length': 8
}
defaults.update(kwargs)
defaults.update(overwrites)
super(DataTypeField, self).__init__(**overwrites)
def to_python(self, value):
return DataType(value)
def get_prep_value(self, value):
return unicode(DataType(value))
def value_to_string(self, obj):
val = self._get_val_from_obj(obj)
return self.get_prep_value(val)
这让我可以做这样的事情:
class FooModel(models.Model):
data = models.TextField()
data_type = DataTypeField()
>>> foo = FooModel.objects.create(data='17.94', data_type=float)
>>> foo.data_type(foo.data)
17.94
>>> type(foo.data_type(foo.data))
float
因此,我的问题是,在Django Admin(我使用的是ModelAdmin)中,文本框中data_type的值没有正确显示。每当它是float
(在db中它存储为float,我选中了),显示的值就是0.0
。对于int
,它显示0
。对于bool
,它显示False
。Django没有显示数据类型的字符串表示形式,而是在某个地方实际调用它,这意味着使用我们的an参数调用\uuuu call\uuuu
,从而生成这些值。例如:
>>> DataType(float)()
0.0
>>> DataType(int)()
0
>>> DataType(bool)()
False
我通过用以下方法替换\uuuu call\uuu
方法,找到了如何对其进行修补的方法:
def __call__(self, *args, **kwargs):
if not args and not kwargs:
return self.__unicode__()
return self.datatype(*args, **kwargs)
这在表单中显示了正确的值,但是我觉得这不是很优雅。有没有办法让它变得更好?我不知道Django首先在哪里调用字段值
Thanxwrt为什么调用您的数据类型,请阅读以下内容:
干净的解决方案可能是简单地将调用重命名为更明确的方式。Django表示从模型派生的模型对象的方式。查看模型的源代码,了解Django是如何做到这一点的。我想这可能是问题所在,但Django管理员不会使用ModelForm哪些字段使用小部件来呈现形式。因此,值的实际呈现不是发生在模板中,而是发生在小部件中。在调试过程中,我单步遍历了小部件,而小部件呈现函数得到了错误的值。