Database 在显示在管理中之前预处理数据库中的值
我的问题很简单,但我无法解决我的问题:每次在管理中显示字段时,我都需要处理一个字段,因为它必须以不同的方式保存在数据库中 例如,我需要用户在admin中输入百分比(比如50、70或100),但这些值将以0.5、0.7或1的形式保存在数据库中。之后,当用户想要编辑或只是查看这些值时,不需要对它们进行预处理以再次显示为percetages(整数),即使它们在数据库中保存为float 我的想法是:Database 在显示在管理中之前预处理数据库中的值,database,django,django-admin,Database,Django,Django Admin,我的问题很简单,但我无法解决我的问题:每次在管理中显示字段时,我都需要处理一个字段,因为它必须以不同的方式保存在数据库中 例如,我需要用户在admin中输入百分比(比如50、70或100),但这些值将以0.5、0.7或1的形式保存在数据库中。之后,当用户想要编辑或只是查看这些值时,不需要对它们进行预处理以再次显示为percetages(整数),即使它们在数据库中保存为float 我的想法是: def valid_percentage(value): if not 0 <= valu
def valid_percentage(value):
if not 0 <= value <= 1:
raise ValidationError(u'Must be a value between 0 and 100')
class PercentageField(models.IntegerField):
def __init__(self, *args, **kwargs):
kwargs['validators'] = kwargs.get('validators', []) + [valid_percentage]
super(PercentageField, self).__init__(*args, **kwargs)
def to_python(self, value):
return None if value is None else int(100 * value)
def get_prep_value(self, value):
return None if value is None else value/100.0
to python 32.0
converted to python 3200
clean 3200
to python 3200
converted to python 320000
def有效_百分比(值):
如果不是0尝试,然后查看数据库,看看哪一步失败 我做了很多,得到了一个版本的代码,可以保存,另一个版本可以显示。这很有趣,但不是很有用
实现您想要的目标的正确方法是:
在模型类定义中使用简单的十进制字段或浮点字段
为您的模型创建一个
在模型表单中定义将输入值除以100
创建并使用自定义小部件类在渲染前将值乘以100
如所述:
必须确保用于表示自定义字段的表单字段执行将用户提供的表单输入转换为与to_python()兼容的模型字段值所需的任何输入验证和数据清理。这可能需要编写一个自定义表单字段,和/或在字段上实现formfield()方法,以返回一个表单字段类,其to_python()返回正确的数据类型
事实上,您也可以采取以下步骤:
创建一个PercentageField类覆盖
创建PercentageFormField,PercentageField.formfield()应调用该字段
创建PercentageWidget默认情况下将使用哪个PercentageFormField
如果您打算按照您建议的方式执行,您将遇到一个错误,这是错误的,即to_python()会被反复调用多次,基本上使用以下代码:
def to_python(self, value):
print 'to python', value
value = None if value is None else int(100 * value)consider this section of the documentation
print 'converted to python', value
return value
从modelform保存模型将输出如下内容:
def valid_percentage(value):
if not 0 <= value <= 1:
raise ValidationError(u'Must be a value between 0 and 100')
class PercentageField(models.IntegerField):
def __init__(self, *args, **kwargs):
kwargs['validators'] = kwargs.get('validators', []) + [valid_percentage]
super(PercentageField, self).__init__(*args, **kwargs)
def to_python(self, value):
return None if value is None else int(100 * value)
def get_prep_value(self, value):
return None if value is None else value/100.0
to python 32.0
converted to python 3200
clean 3200
to python 3200
converted to python 320000
如果你坚持想用错误的方式做,你就必须使用
结论:
感谢SmileyChris在这个答案中提供的帮助,这可能并不完美,但我认为如果不分享我的发现,那就太糟糕了。您可能不应该将IntegerField
子类化,因为您不打算在数据库中存储整数。请改为尝试DecimalField
或FloatField
。