Django REST Framework:响应中缺少序列化器字段

时间:2018-08-12 09:50:01

标签: django django-rest-framework

我正在使用Django 2.0Django REST Framework

我有以下两个模型contacttransaction

联系方式

class Contact(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100, blank=True, null=True)

给定型号的数量

class AmountGiven(models.Model):
    contact = models.ForeignKey(Contact, on_delete=models.PROTECT)
    amount = models.FloatField(help_text='Amount given to the contact')
    interest_rate = models.FloatField(blank=True, default=None, null=True, help_text='% of interest to be calculated')
    _given_date = models.DateTimeField(
        db_column='given_date',
        default=timezone.now,
        help_text='Date and time when amount was given to the contact'
    )

    def __str__(self):
        return str(self.amount)

    @property
    def given_date(self):
        return self._given_date

    @given_date.setter
    def given_date(self, value):
        self._given_date = value

    @property
    def interest_to_pay(self):
        if self.interest_rate:    
            datetime_diff = datetime.now(get_localzone()) - self.given_date
            days = datetime_diff.days
            duration_in_year = days/365

            simple_interest_amount = (self.amount * duration_in_year * self.interest_rate)/100

            return simple_interest_amount

        return 0

    @property
    def total_payable(self):
        return self.amount + self.interest_to_pay

    @property
    def amount_due(self):
        returned_amount = 0
        for returned in self.amountreturned_set.all():
            returned_amount += returned.amount

        return self.total_payable - returned_amount

ContactSerializer

class ContactSerializer(serializers.HyperlinkedModelSerializer):
    url = serializers.HyperlinkedRelatedField(
        view_name='contacts:detail',
        read_only=True
    )

    user = serializers.CurrentUserDefault()

    amount_due = ReadOnlyField(source='amountgiven__amount_due')

    class Meta:
        model = Contact
        fields = ('url', 'id', 'first_name', 'last_name', 'full_name', 'amount_due')

views.py

class ContactViewSet(viewsets.ModelViewSet):
    serializer_class = ContactSerializer
    permission_classes = (IsAuthenticated, AdminAuthenticationPermission,)

    def get_queryset(self):
        return Contact.objects.filter(user=self.request.user)

    def perform_create(self, serializer):
        serializer.save(user=self.request.user)

但是在使用amount_due方法向url端点发出请求时,返回的响应中没有/contacts/GET字段。

2 个答案:

答案 0 :(得分:2)

根据您的评论,您需要所有金额的总和(请编辑您的问题)。因此您应该在查询集中使用注释:

from django.db.models import Sum

def get_queryset(self):
    return Contact.objects.filter(user=self.request.user).annotate(amount_due=Sum('amountgiven_set__amount'))

(我建议对查询集和过滤使用modelManager,而不是在此处进行操作)

并将这样的字段添加到序列化器中:

amount_due = serializer.IntegerFiled()

答案 1 :(得分:0)

您的建模方式不允许您以所需的方式访问amount_due。

您的Contact模型没有amountgiven属性。 但是,它确实具有amountgiven_set,可用于获取给定联系人的数量查询集。

但是可以有多个,因此您需要确定要在序列化程序中显示哪个amount_due

您可以使用SerializerMethodField来序列化您想要的amount_due的值:

class ContactSerializer(serializers.HyperlinkedModelSerializer):
    amount_due = serializers.SerializerMethodField()

    def get_amount_due(self, obj):
         amountgiven = obj.amountgiven_set.first()
         return amountgiven.amount_due

但是再次,正如我已经提到的-amountgiven_set返回一个查询集,您可以在其中拥有多个对象。

如果确定给定联系人只有一个,则可以像我的示例中那样使用first()来获取它。