I just started using Django & Django REST framework. I have the following models:
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)
The idea would be to read the vat_perc
value inside the account
record the user has just selected and to perform a calculation to determine the total_amount
value which then should be saved in the entry
record on the database (I know some would regard this as suboptimal due to the duplication of data in the database; please follow me anyway).
The total_amount
field should be regularly serialized when requested. Instead, the serializer should not do anything for deserialization, because the overriding of the save
method in the model takes care of updating values if a creation or modification occurs. If I get the documentation correctly, all this means setting the total_amount
field in the serializer class as read_only
.
Now, these are my serializers:
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)
But this is the error I get:
Got a
TypeError
when callingEntry.objects.create()
. This may be because you have a writable field on the serializer class that is not a valid argument toEntry.objects.create()
. You may need to make the field read-only, or override the EntrySerializer.create() method to handle this correctly. Original exception text was: int() argument must be a string, a bytes-like object or a number, not 'Account'.
The last sentence sounds particularly obscure to me. Am I getting something wrong? Any hint? Thanks in advance.
Thanks to Claudiu. Used SlugRelatedField
in the serializer class and decimal.Decimal
type instead of float
as I did mistankenly. The following code now works:
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")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With