如何在 Django Rest Framework 中显示嵌套对象的属性

编码

我正在使用 Django 和 Django-Rest-Framework 为战斗系统构建 API。在我的代码中,我有 2 个模型:父模型Battle和子模型RoundRound有一些start_time, end_time, score基于不同值计算的@property 字段 ( )。当我Round直接访问路线时,我得到了所需的输出:

http://127.0.0.1:8001/battle/rounds/1/

{
    "id": 1,
    "battle": "http://127.0.0.1:8001/battle/battles/1/",
    "index": 0,
    "contender_entry": null,
    "opponent_entry": null,
    "start_time": "2019-12-11T17:38:00Z",
    "end_time": "2019-12-11T17:39:40Z",
    "score": [
        0,
        0
    ]
}

但是,当我访问Battle路由时,Round会返回嵌套的s,但返回数据库字段,而不返回属性:

http://127.0.0.1:8001/battle/battles/1/

{
    "url": "http://127.0.0.1:8001/battle/battles/1/",
    "id": 1,
    "status": "live",
    "start_time": "2019-12-11T17:38:00Z",
    "round_length": "00:01:40",
    ...
    "rounds": [
        {
            "url": "http://127.0.0.1:8001/battle/rounds/1/",
            "beat": null,
            "index": 0,
            "battle": "http://127.0.0.1:8001/battle/battles/1/",
            "contender_entry": null,
            "opponent_entry": null
        },
        {
            "url": "http://127.0.0.1:8001/battle/rounds/2/",
            "beat": null,
            "index": 1,
            "battle": "http://127.0.0.1:8001/battle/battles/1/",
            "contender_entry": null,
            "opponent_entry": null
        },
        {
            "url": "http://127.0.0.1:8001/battle/rounds/3/",
            "beat": null,
            "index": 2,
            "battle": "http://127.0.0.1:8001/battle/battles/1/",
            "contender_entry": null,
            "opponent_entry": null
        }
    ],
    "current_round": null
}

我希望属性显示RoundBattle. 但我无法让它工作。

这些是我的模型:

class Round(models.Model):
    battle = models.ForeignKey(Battle, on_delete=models.CASCADE, related_name="rounds")
    index = models.IntegerField()
    contender_entry = models.OneToOneField(Entry, on_delete=models.DO_NOTHING, related_name="round_contender",
                                           null=True)
    opponent_entry = models.OneToOneField(Entry, on_delete=models.DO_NOTHING, related_name="round_opponent", null=True)

    @property
    def start_time(self):
        return self.battle.start_time + (self.index * self.battle.round_length)

    @property
    def end_time(self):
        return self.start_time + self.battle.round_length

    @property
    def score(self):
        opponent_votes = self.votes.filter(favors="opponent").count()
        contender_votes = self.votes.filter(favors="contender").count()
        draw_votes = self.votes.filter(favors="draw").count()
        return (opponent_votes + draw_votes, contender_votes + draw_votes)

class Battle(models.Model):
    status = models.CharField(max_length=32, choices=BATTLE_STATUS_CHOICES, default="awaiting_approval")
    contender = models.ForeignKey(User, on_delete=models.CASCADE, related_name="contender_battles")
    opponent = models.ForeignKey(User, on_delete=models.CASCADE, related_name="opponent_battles")
    start_time = models.DateTimeField(default=timezone.now)
    round_length = models.DurationField(default=timedelta(days=3))

和序列化程序:

class RoundSerializer(serializers.HyperlinkedModelSerializer):
    id = serializers.IntegerField(source="pk", read_only=True)

    class Meta:
        model = Round
        fields = ["id", "battle", "index", "contender_entry", "opponent_entry", "start_time", "end_time", "score"]
        read_only_fields = ["id", "battle", "index", "start_time", "end_time", "score"]

class BattleSerializer(serializers.HyperlinkedModelSerializer):
    id = serializers.IntegerField(source='pk', read_only=True)
    current_round = RoundSerializer(read_only=True)

    class Meta:
        model = Battle
        fields = ["url", "id", "status", "start_time", "round_length",
                  "opponent", "contender", "rounds", "current_round"]
        read_only_fields = ["contender", "rounds", "status"]


class BattleReadSerializer(BattleSerializer):
    contender = UserSerializer(read_only=True)
    opponent = UserSerializer(read_only=True)

    class Meta:
        model = Battle
        fields = ["url", "id", "status", "start_time", "round_length",
                  "opponent", "contender", "rounds", "current_round"]
        read_only_fields = ["contender", "rounds"]
        depth = 1

请注意,我有 2 个 Battle 序列化程序:BattleSerializer用于 POST 和 PUT 以及用户超链接而不是嵌套字段。BattleReadSerializer用于 GET 并嵌套输出。BattleReadSerializer是上面例子中使用的那个。

我已经尝试将字段RoundSerializer显式添加到,如下所示:

class RoundSerializer(serializers.HyperlinkedModelSerializer):
    id = serializers.IntegerField(source="pk", read_only=True)
    start_time = serializers.DateTimeField(read_only=True)
    score = serializers.ListField(read_only=True)

但这并没有改变任何事情。有没有办法让属性字段显示出来(除了让它们成为数据库字段并经常重新计算它们)?

JPG

尝试将RoundSerializer序列化程序显式添加BattleReadSerializer序列化程序中,如下所示,

class BattleReadSerializer(BattleSerializer):
    contender = UserSerializer(read_only=True)
    opponent = UserSerializer(read_only=True)
    rounds = RoundSerializer(read_only=True, many=True)

    class Meta:
        model = Battle
        fields = ["url", "id", "status", "start_time", "round_length",
                  "opponent", "contender", "rounds", "current_round"]
        read_only_fields = ["contender", "rounds"]
        
     
     
      
      depth = 1
     
       # remove this

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在Django REST Framework中处理嵌套对象

如何在Django Rest Framework中列出相关对象

如何在Django Rest Framework中哈希Django用户密码?

如何在Django Rest Framework可浏览API中显示对象详细信息?

如何在 Django Rest Framework 中添加后缀 url?

如何在Django Rest Framework中的动作内进行分页

如何在Django Rest Framework中验证只读字段

如何在Django REST Framework中修复UnicodeDecodeError?

如何在django-rest-framework POST中包含ForeignKey

如何在Django Rest Framework(DRF)中覆盖Response类?

Django Rest Framework:如何在ModelViewSet中关闭/打开分页

如何在Django REST Framework中禁用身份验证

如何在Django Rest Framework中动态设置分页?

如何在Django Rest Framework中序列化ChoiceFields?

如何在 Django REST Framework 中捕获 PermissionDenied 异常

如何在Django Rest Framework中以403错误返回数据?

如何在Django Rest Framework中获得模型方法的价值?

如何在Django Rest Framework API中隐藏网址?

如何在Django rest Framework中执行Delete操作?

如何在Python(Django Rest Framework模板)中修复UnicodeDecodeError?

如何在Django Rest Framework中处理文件?

如何在Django REST Framework中实现简单的“喜欢”功能?

如何在Django Rest Framework中动态更新视图集

如何在Django Rest Framework中不转义字符

如何使用Django Rest Framework视图集按父对象的属性过滤嵌套数据

Django REST Framework 如何检索嵌套关系

如何使用Django Rest Framework删除对象

如何在Django Rest Framework中过滤嵌套的序列化器?

如何在Django Rest Framework中建立嵌套关系的超链接字段?