【问题标题】:Django Rest Framework Limiting get_queryset result to not include all fieldsDjango Rest框架限制get_queryset结果不包括所有字段
【发布时间】:2020-01-31 15:00:24
【问题描述】:

view.py

class charity_totals(generics.ListAPIView):
    serializer_class= CharityTotalSerializer
    queryset=Transaction.objects.all()
    def get_queryset(self):
        queryset = super().get_queryset()
        user_id = self.request.GET.get('userID')
        if user_id is None:
            return queryset
        queryset = queryset.filter(userID=user_id)
        return queryset.values('charityID').annotate(total_donation=Sum('transactionAmount'))

serializer.py

class CharityTotalSerializer(ModelSerializer):
    charity_name= serializer.ReadOnlyField(source='charityID.charityName')
    total_donation= serializer.DecimalField(max_digits=64,decimal_places=2)
    class Meta:
        model = Transaction
        fields = ['charity_name','total_donation']

型号

class Transaction(models.Model):
    transactionAmount = models.DecimalField(max_digits=6, decimal_places=2)
    userID = models.ForeignKey(User,on_delete=models.CASCADE)
    charityID = models.ForeignKey(Charity,on_delete=models.CASCADE, related_name='charity_set')
    processed = models.BooleanField(auto_created=True, default=False)
    transactionDate = models.DateField(auto_now_add=True)

关闭诸如 http://localhost:8000/requests/charitytotal/?userID=1 这样的请求,我的 json 响应仅限于 [{"total_donation":"3.00"},{"total_donation":"17.00"}] 并且不包括慈善机构名称在序列化程序中指定。据我了解,.values 应该返回charityID 和指定的total_donation 的字典,它们应该能够与我的序列化程序交互。任何见解将不胜感激

【问题讨论】:

    标签: django django-rest-framework


    【解决方案1】:

    这是因为当您在 request.GET 中获取 userID 的值时,您正在从 get_queryset 方法返回 Values 查询集。此外,我认为以这种方式返回对您很重要,这样您就可以按总捐赠的值进行分组和求和。所以,我认为你可以这样处理:

    首先,更改get_queryset方法,返回标注的慈善机构名称:

    from django.db.models import F, Sum
    ...
    
    def get_queryset(self):
        queryset = super().get_queryset()
        user_id = self.request.GET.get('userID')
        if user_id is not None:
            queryset = queryset.filter(userID=user_id)
        return queryset.values('charityID').annotate(total_donation=Sum('transactionAmount')).annotate(charity_name=F('charityID__charityName'))
    

    然后像这样更新序列化器:

    class CharityTotalSerializer(ModelSerializer):
        charity_name= serializer.ReadOnlyField()  # no need to define source
        total_donation= serializer.DecimalField(max_digits=64,decimal_places=2)
        class Meta:
            model = Transaction
            fields = ['charity_name','total_donation']
    

    另外,最好有charityName 唯一(在模型中使用unique=True),这样它就不会产生令人困惑的结果。

    【讨论】:

      【解决方案2】:

      你必须把它放到 Serializer 中,它才能正常工作。

      charity_name = serializer.SerializerMethodField()
      
      def get_charity_name(self, instance):
          return instance.charityID.name
      

      【讨论】:

      • 仅代码的答案被认为是低质量的:请务必说明您的代码的作用以及它如何解决问题。如果您可以在帖子中添加更多信息,它将帮助提问者和未来的读者。另请参阅解释完全基于代码的答案:meta.stackexchange.com/questions/114762/…
      猜你喜欢
      • 1970-01-01
      • 2015-12-15
      • 2015-08-24
      • 2019-07-13
      • 2020-12-20
      • 1970-01-01
      • 1970-01-01
      • 2021-06-07
      • 2013-10-08
      相关资源
      最近更新 更多