呈现具有不同表示形式的Django表单字段时出现问题

呈现具有不同表示形式的Django表单字段时出现问题,django,django-forms,Django,Django Forms,我已经为百分比实现了一个自定义表单字段(的修改版本)。我和世界上其他人一样,也在这样做:将0.25的值显示为25%。为了实现这一点,我们需要在显示之前将该值乘以100,并在保存时将其除以100(见下文) 保存部分(clean)工作正常,但问题在于显示值(render或者更确切地说是prepare\u value)。有不同类型的值被传递到prepare\u value。它可能是您的默认值(我的值为0),因此它可能是整数,但也可能是十进制(大多数情况下),因为它毕竟是一个十进制字段 当表单抛出错误并

我已经为百分比实现了一个自定义表单字段(的修改版本)。我和世界上其他人一样,也在这样做:将0.25的值显示为25%。为了实现这一点,我们需要在显示之前将该值乘以100,并在保存时将其除以100(见下文)

保存部分(
clean
)工作正常,但问题在于显示值(
render
或者更确切地说是
prepare\u value
)。有不同类型的值被传递到
prepare\u value
。它可能是您的默认值(我的值为0),因此它可能是整数,但也可能是十进制(大多数情况下),因为它毕竟是一个十进制字段

当表单抛出错误并且需要重新显示值时,就会出现问题。在这种情况下,表单值将被传递给它-这是一个unicode。因此,我们不需要像以前那样将值乘以100(更准确地说:因为值可以是不同于十进制的值-即int或unicode-我们只需要在它不是十进制时将其相乘。也就是说-十进制字段)。正如你所看到的,我使用了
isinstance
来解决这个问题

我开始觉得我真的不明白这里发生了什么,我也不知道如何才能正确地解决这个问题。有什么建议吗

class PercentInput(TextInput):
    def render(self, name, value, attrs=None):
        from django.utils.safestring import mark_safe
        return super(PercentInput, self).render(name, value, attrs) + \
               mark_safe(u' %')


class PercentField(DecimalField):
    widget = PercentInput(attrs={'size': 4, 'maxlength': 5})

    default_error_messages = {
        'positive': _(u'Must be a positive number.'),
    }

    def prepare_value(self, value):
        if isinstance(value, Decimal):
            value *= 100
        return super(PercentField, self).prepare_value(value)

    def clean(self, value):
        value = super(PercentField, self).clean(value)
        if value is None:
            return None
        if value < 0:
            raise ValidationError(self.error_messages['positive'])
        return Decimal('%.4f' % (value / 100))
类百分比输入(TextInput):
def render(自身、名称、值、属性=无):
从django.utils.safestring导入标记_safe
返回super(PercentInput,self).render(名称,值,属性)+\
标记u安全(u“%”)
类别百分比字段(十进制字段):
小部件=百分比输入(属性={'size':4,'maxlength':5})
默认错误消息={
“正数”:(u'必须是正数。“),
}
def准备_值(自身,值):
如果isinstance(值,十进制):
值*=100
返回超级(百分比字段,自我)。准备_值(值)
def清洁(自身,值):
值=超级(百分比字段,自).clean(值)
如果值为“无”:
一无所获
如果值<0:
引发ValidationError(self.error_消息['positive']))
返回小数点(“%.4f%”(值/100))

> p>您可以考虑使用MultValueFieldMulnWuIGET。多值字段的优点是它有一个压缩方法,您可以利用它来获取输入并将其转换为十进制形式,而MultiWidget有一个解压方法来获取该十进制并将其转换为字符串,并以您想要的方式显示

我写了一个将十进制数转换为英尺、英寸和分数英寸(10'3 1/2英寸,以123.5的形式存储在数据库中)的程序,它几乎可以满足您的需要。希望这能帮您解决问题!

我仍然对上面的代码“执迷”不放。毕竟,它是按预期工作的。您提出的多重解决方案可能会工作,但感觉有点“沉重”“为了我的小问题。(这毕竟不是多值字段。)