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

标签 django django-forms

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

保存部分( clean )工作正常,但问题在于显示值( render 或更确切地说 prepare_value )。传递给 prepare_value 的值有多种类型.它可能是你的默认值(我的是 0)所以它是一个 int 但它也可能是一个 Decimal(大部分时间)因为它毕竟是一个 DecimalField。

当表单抛出错误并且需要重新显示值时,就会出现问题。在这种情况下,表单值将传递给它 - 这是一个 unicode。因此,我们不需要像以前那样将值乘以 100(更准确地说:由于该值可能与 Decimal 不同 - 即 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))

最佳答案

您可能会考虑将 MultiValueField 与 MultiWidget 结合使用。会给你带来的好处是 MultiValueField 有一个压缩方法,你可以利用它来获取输入并将其转换为十进制形式,而 MultiWidget 有一个解压缩方法来获取小数并将其转换为字符串并显示它你想要怎么样。

我写了一个 Feet and Inches widget将小数转换为英尺、英寸和小数英寸(10' 3 1/2",在数据库中存储为 123.5),这几乎可以满足您的需求。希望对您有所帮助!

关于django - 呈现具有不同表示形式的 Django 表单字段时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6690692/

相关文章:

python - django、uni_form 和 python 的 __init__() 函数 - 如何将参数传递给表单?

python - Fabric 导入错误 : cannot import name 'isMappingType'

python - Django userena 错误 Reverse for 'password_reset_done',参数 '()' 和关键字参数 '{}' 未找到。尝试了 0 个模式 : []

python - 从 URL 获取协议(protocol) + 主机名

python - Django:如何显示选项的名称而不是整数?

django - 如何在 Django 的同一个模板中使用两个 ckeditor?

python - django - 将用户 ID 添加到 UpdateView

Django 表单字段分组

python - 由于 errno : 150 "Foreign key constraint is incorrectly formed",Django 1.8 应用程序初始迁移神秘失败

python - 如何 : Click button, 然后做东西,然后在 Django 中显示确认