我正在尝试获取基于外键的数据。 假设我有这些模型:
# 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/