【问题标题】:Multi field and computed value多字段和计算值
【发布时间】:2011-11-11 23:40:59
【问题描述】:

我需要解决这个问题:

我想要一个“值”字段的 MultiField 小部件。该字段应该允许输入两个值(两个输入小部件),并且用户应该选择要保存这些值中的哪一个(两个复选框小部件)。但是,必须根据其他字段的值重新计算其中一个值。

我采用了这种方法: MultiValueField 有 4 个字段:

class PriceDetailField(MultiValueField):
    use_net = BooleanField(required=False)
    net_value = DecimalField(required=False, decimal_places=2)
    use_gross = BooleanField(required=False)
    gross_value = DecimalField(required=False, decimal_places=2)

一个MultiWidget:

class PriceDetailWidget(MultiWidget):
    use_net = CheckboxInput()
    net_value_widget = TextInput()
    use_gross = CheckboxInput()
    gross_value_widget = TextInput()

还有一个自定义表单...

class PriceModelForm(ModelForm):
    value = PriceDetailField()

...覆盖模型的默认模型形式:

class Price(models.Model):
    value = models.DecimalField(
        max_digits=19,
        decimal_places=2,
        default=Decimal(0),
        )

但是,这个解决方案似乎搞砸了。在表单中,我需要输入所有子字段(MultiValueField 子字段),否则会出现“请输入值”错误(即使这些字段标记为required=False)。还, 我必须在保存时重新计算提到的值,从字段返回一个元组,其中包含已选中复选框的信息和相应的文本值,然后用clean_value 表单方法中的十进制值替换元组(另外,保存复选框临时字段中的状态....)。我觉得这样的设计很弱。

表单应该既可以独立工作,也可以作为内联工作(这意味着,用于计算返回值的字段的值可以在保存期间更改,也可以不更改)。

这样的事情有可能吗?


问题的根源:我想将商品的价格存储为净价,但我希望允许用户将它们输入为净价或毛价,然后根据产品的增值税将毛价重新计算为净价税级(因为增值税分配给产品或服务,而不是价格)。一个产品可以有多个价格,因此价格通过外键反向链接到该产品。

干杯, 托梅克

【问题讨论】:

    标签: django django-models django-admin django-forms django-widget


    【解决方案1】:

    您在 MultiValueField 上寻找的功能(允许子字段是必需的或不单独的)记录为 a feature request on Django

    您现在可以通过根据错误报告中的原始建议和以下建议使用重写的clean 方法子类化MultiValueField 来解决此问题。不过到那时你不会留下很多原始的MultiValueField,如果你这样做了,你应该将你的补丁提交给 Django 并在错误上写下注释。

    暂时忽略必要的事情,你有没有在你的PriceDetailField 上写一个compress 方法?它是什么样子的?这是您应该做的工作,将您的四个子字段变成一个单独的字段来保存。

    【讨论】:

    • 我通过 MultiValueField clean 方法,我意识到它调用了 compress。因此,要做的就是正确实现 compress 方法。现在,它返回计算的小数(因为,我在构造时将整个表单链接到字段,所以我可以访问计算 MVF 字段值所需的字段),抛出 ValidationError(如果子字段的组合是非法的)或返回 None .我还必须重新实现 MultiWidget 的 _has_changed 方法。表单中没有字段逻辑,除了传递表单对字段的引用。
    • 您能否指定如何在模板中单独访问 MultiValueField 的子字段?
    猜你喜欢
    • 2011-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-15
    • 2018-07-19
    • 1970-01-01
    • 1970-01-01
    • 2015-12-03
    相关资源
    最近更新 更多