Django Rest Framework:除了默认模型字段之外还有其他数据的响应,其中附加数据需要来自sql查询

时间:2015-06-06 13:13:39

标签: django-rest-framework

我是django和django休息框架的新手,并尝试构建一个应该与手机通信的应用程序。

目前我正在尝试创建一个响应,该响应不仅应包含所请求的模型字段,还应添加一些其他数据,这些数据应首先从另一个模型计算。

我的代码中有2个模型: 比尔 2. BillComment(拥有Bill模型的外键)

这是一个很多(BillComment)到一个(Bill)的关系。 我需要在回复中附上BillComment表中与特定账单相关的评论数量。

这是我当前的代码, NOT 正在运行:

models.py

class BillComment(models.Model):

    bill    = models.ForeignKey(Bill)    
    user    = models.ForeignKey(User)  
    responsed_to = models.ForeignKey('rest_api.BillComment', null=True, blank=True) 
    date    = models.DateTimeField()
    content = models.CharField(max_length=500, default='')

    def __str__(self):
        return '%s %s %s %s %s' % (self.bill, self.user, self.responsed_to, self.date, self.content)

serializers.py

class BillSerializer(serializers.ModelSerializer):
    comments_count = serializers.SerializerMethodField()

    def get_comments_count(self, foo):
        comments_co = BillComment.objects.filter(bill=data.bill).count()
        return comments_co;

    class Meta:
        model = Bill
        fields = ('id', 'subject', 'date', 'description', 'status', 'parliament_member', 'comments_count')

正如您所看到的,我尝试使用其他参数进行响应。 我需要一些如何读取所请求的帐单行的ID,以便我可以过滤所有BillComment行,其中' bill'字段(这是一个外键)指向序列化的同一个帐单。

我该怎么做?

也许我有更合适的解决方案,然后使用SerializerMethodField,请告诉我如何正确地做到这一点。

感谢。

1 个答案:

答案 0 :(得分:1)

您当前的代码只有一个开关远离正确,因为几乎所有设置都正确。 SerializerMethodField传递当前正在序列化的对象作为方法的第一个参数,在您的情况下是被序列化的Bill对象。

因此,您的get_comments_count方法只需要看起来像

def get_comments_count(self, bill):
    comments_co = BillComment.objects.filter(bill=bill).count()
    return comments_co

一切都应该按预期工作。

您可以通过修改查询集来使用Count annotations而不是手动calling .count()来更快地完成此操作,这将为您节省 n 额外查询,并在同一时间提高性能时间。您需要做的就是将.annotate(comments_count=Count('billcomment_set'))添加到视图的当前查询集的末尾,然后将comments_count字段作为IntegerField添加到序列化程序。

queryset = Bill.objects.all().annotate(comments_count=Count('billcomment_set'))

你的序列化器将成为

class BillSerializer(serializers.ModelSerializer):
    comments_count = serializers.IntegerField(read_only=True)

    class Meta:
        model = Bill
        fields = ('id', 'subject', 'date', 'description', 'status', 'parliament_member', 'comments_count')

这是因为comments_count属性将添加到查询集返回的每个对象中,并且序列化程序将像任何其他字段一样序列化它。