代码之家  ›  专栏  ›  技术社区  ›  Anuj TBE

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

  •  0
  • Anuj TBE  · 技术社区  · 7 年前

    Django 2.0 Django REST Framework .

    我有两个模型 contact transaction 如下所示

    接触模型

    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
    

    联系人序列化程序

    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')
    

    视图.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 回复  |  直到 7 年前
        1
  •  0
  •   Enthusiast Martin    7 年前

    您的建模不允许您以所需的方式访问应付金额。

    你的 Contact 模型没有 amountgiven 属性。 但它确实有 amountgiven_set 您可以使用它来获取给定联系人的给定金额的查询集。

    但是可以有多个,所以你需要决定 amount_due

    你可以用 SerializerMethodField

    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返回一个queryset,其中可以有多个对象。

    first() 就像我的例子一样。

        2
  •  2
  •   Ehsan Nouri    7 年前

    根据您的评论,您需要所有金额的总和(请编辑您的问题)。所以您应该在queryset中使用annotate:

    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'))
    

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

    amount_due = serializer.IntegerFiled()