我是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,请告诉我如何正确地做到这一点。
感谢。
答案 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
属性将添加到查询集返回的每个对象中,并且序列化程序将像任何其他字段一样序列化它。