python - Django - 基于外键向序列化器和订单列表添加属性

标签 python django django-rest-framework

我正在尝试获取基于外键的数据。 假设我有这些模型:

# models.py
class Player(models.Model):
    name = models.CharField(max_length = 64)

class Game(models.Model):
    score = models.IntegerField()
    player = models.ForeignKey('Player', models.DO_NOTHING, related_name='player', blank=False, null=False)

class InjuredPlayer(models.Model):
    player = models.ForeignKey('Player', models.DO_NOTHING, blank=False, null=False)

我正在使用 REST 框架,所以我有这个序列化器。我想向 Player 序列化器添加一个属性,该属性是所有游戏分数的总和。

# Serializer
class PlayerSerializer(serializers.ModelSerializer):
    # Get the sum of Game scores of the player
    # sum_of_scores = ________________
  class Meta:
    model = Player
    # Use sum_of_scores as a field on the serializer
    fields = ('activity', 'logo', 'sum_of_scores')

然后,想要做的是显示球员列表及其得分总和(如果他们在 InjuredPlayer 上)。所以在我的类里面:

class PlayerList(APIView)

查询集应该类似于:

# I tried this
queryset = Player.objects.filter(injuredplayer__player=id)

如何过滤不在其他表中的对象。 是否可以根据 sum_of_scores 对列表进行排序?如果是这样,怎么办? 谢谢

最佳答案

如果你想获得序列化器中所有字段的总和,请使用serializerMethodField

from django.db.models import Sum
# also import Game model
class PlayerSerializer(serializers.ModelSerializer):
    sum_of_scores = serializers.SerializerMethodField()

    class Meta:
        model = Player
        fields = ('id', 'name', 'sum_of_scores')

    def get_sum_of_scores(self, obj):
        return Game.objects.filter(player=obj).aggregate(Sum('score'))

注意 您的模型结构不是最佳的,您可以删除 InjuredPlayer 模型,并为 Player 添加新字段,例如 is_injured 。并将其设置为默认 false。而且游戏模型相关的名称应该是“游戏”之类的。以便您可以轻松地反向引用。在您当前的结构中,要获取与玩家相关的所有游戏,您应该调用player.player.all()。如果你把它改为游戏,那就是player.games.all()

所以新的结构应该是

# models.py
class Player(models.Model):
    name = models.CharField(max_length = 64)
    is_injured = models.BooleanField(dafault=False)

class Game(models.Model):
    score = models.IntegerField()
    player = models.ForeignKey('Player', models.DO_NOTHING, related_name='games', blank=False, null=False)

序列化器变成

# Serializer
from django.db.models import Sum
class PlayerSerializer(serializers.ModelSerializer):
    sum_of_scores = serializers.SerializerMethodField()

    class Meta:
        model = Player
        fields = ('id', 'name', 'is_injured', 'sum_of_scores')

    def get_sum_of_scores(self, obj):
        return obj.games.all().aggregate(Sum('score'))

关于python - Django - 基于外键向序列化器和订单列表添加属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49248804/

相关文章:

python - timeit 吃掉返回值

python - django rest framework 离线文档

django - 在安装 Django-nonrel 之前是否需要卸载 Django 1.3?

python - Django Rest 框架序列化程序关系 : How to get a list of only the latest track?

python - 使用列表理解替换 m x n 数组中的元素

python - 如何使用 selenium webdriver Python 单击没有 lisk 的 span 按钮?

python - 从静态文件夹检索图像时如何防止 404 错误

python - django 和 dropzone 如何发布表单

python - 努力让 django_comments 与 Django REST Framework 一起工作

python - 为整个结果集向 Django Rest Framework 结果添加额外数据