我刚刚开始使用Django和Django REST框架。我有以下型号:

class Account(models.Model):
    name = models.CharField(max_length=100, blank=False)
    vat_perc = models.DecimalField(max_digits=4, decimal_places=2)
    def __str__(self):
        return "ACCOUNT: {0} -- {1}".format(self.name, str(self.vat_perc))


class Entry(models.Model):
    account = models.ForeignKey(Account)
    description = models.CharField(max_length=100)
    taxable_income = models.DecimalField(max_digits=10, decimal_places=2)
    total_amount = models.DecimalField(max_digits=10, decimal_places=2, null=True)

    def save(self, *args, **kwargs):
        selected_vat = Account.objects.get(pk=self.account).vat_perc
        self.total_amount = self.taxable_income * (100.00+selected_vat)/100.00
        super(Entry, self).save(*args, **kwargs)

这个想法是读取用户刚刚选择的vat_perc记录内的account值,并执行计算以确定total_amount值,然后将其保存在数据库的entry记录中(我知道有些人会将此视为次优的)数据库中的重复数据;无论如何请关注我)。

要求时,应定期将total_amount字段序列化。相反,序列化程序不应该执行任何反序列化操作,因为在模型中覆盖save方法会在创建或修改发生时负责更新值。如果我正确地获得了文档,则所有这些都意味着将序列化程序类中的total_amount字段设置为read_only

现在,这些是我的序列化器:
class AccountSerializer(serializers.ModelSerializer):
    class Meta:
        model = Account
        fields = ('id', 'name', 'vat_perc',)


class EntrySerializer(serializers.ModelSerializer):
    class Meta:
        model = Entry
        fields = ('id', 'account', 'description', 'taxable_income', 'total_amount',)

    total_amount = serializers.ReadOnlyField()
    # alternatively: total_amount = serializers.FloatField(read_only=True)

但这是我得到的错误:



最后一句话听起来对我特别晦涩。我有什么问题吗?有什么提示吗?
提前致谢。

最佳答案

感谢Claudiu。在序列化器类中使用SlugRelatedFielddecimal.Decimal类型代替float,就像我an昧地做的那样。现在,以下代码可以工作:

class Account(models.Model):
    name = models.CharField(max_length=100, blank=False)
    vat_perc = models.DecimalField(max_digits=4, decimal_places=2)
    def __str__(self):
        return "ACCOUNT: {0} -- {1}".format(self.name, str(self.vat_perc))


class Entry(models.Model):
    account = models.ForeignKey(Account)
    description = models.CharField(max_length=100)
    taxable_income = models.DecimalField(max_digits=10, decimal_places=2)
    total_amount = models.DecimalField(max_digits=10, decimal_places=2, null=True)

    def save(self, *args, **kwargs):
        self.total_amount = self.taxable_income * (decimal.Decimal(100.00) + self.account.vat_perc) / decimal.Decimal(100.00)
        super(Entry, self).save(*args, **kwargs)

serializers.py
class AccountSerializer(serializers.ModelSerializer):
    class Meta:
         model = Account
         fields = ('id', 'name', 'vat_perc',)


class EntrySerializer(serializers.ModelSerializer):
    class Meta:
        model = Entry
        fields = ('id', 'account', 'description', 'taxable_income', 'total_amount',)

    total_amount = serializers.ReadOnlyField()
    account = serializers.SlugRelatedField(queryset=Account.objects.all(), slug_field="vat_perc")

10-06 01:46