【问题标题】:Django rest framework. Return multiple models nestedDjango 休息框架。返回嵌套的多个模型
【发布时间】:2019-11-23 09:13:40
【问题描述】:

我正在尝试创建一个组合视图集,以嵌套格式显示来自三个 django 模型的数据。

我在尝试返回视图集时收到错误消息。

Got AttributeError when attempting to get a value for field `runner` on serializer `CombinedSerializer`. The serializer field might be named incorrectly and not match any attribute or key on the `Runner` instance. Original exception text was: 'Runner' object has no attribute 'runner'.

序列化器.py

class CombinedSerializer(serializers.Serializer):
    event = EventSerializer()
    market = MarketSerializer()
    runner = RunnerSerializer()
    class Meta:
        fields = ('event' , 'market', 'runner')

views.py

class CombinedViewSet(mixins.ListModelMixin, 
                      viewsets.GenericViewSet, 
                     mixins.RetrieveModelMixin):

    queryset = Runner.objects.all()
    serializer_class = CombinedSerializer

models.py

class Event(models.Model):
    sport_id = models.CharField(max_length=15)
    event_id = models.BigIntegerField(unique=True)
    event_name = models.CharField(max_length=200)
    start_time = models.DateTimeField(null=True)
    status = models.CharField(max_length=13)


class Market(models.Model):
    event = models.ForeignKey(Event, on_delete=models.CASCADE)
    market_id = models.BigIntegerField(unique=True)
    market_name = models.CharField(max_length=35)
    status = models.CharField(max_length=10)
    volume = models.FloatField(null=True)

class Runner(models.Model):
    event = models.ForeignKey(Event, null=True, default=None, on_delete=models.CASCADE)
    market = models.ForeignKey(Market, null=True, default=None, on_delete=models.CASCADE)
    runner_id = models.BigIntegerField(unique=True)
    name = models.CharField(max_length=500)
    back_odds = models.FloatField(null=True)
    lay_odds = models.FloatField(null=True)

由于某种原因,当我从我的 api 中以嵌套格式显示的序列化程序事件和市场中删除运行器时。当我添加 Runner 时,出现上述错误。如何解决此问题并在我的 API 中显示所有三个?

【问题讨论】:

  • 序列化器认为“Combined Serializer”正在序列化“Runner”模型。因为“Runner”是查询集。尝试取出跑步者,然后在“字段”元组中列出你想要的跑步者模型中的所有字段。
  • @Neil 如果我在字段元组中添加来自跑步者模型的字段,序列化程序如何知道这些字段属于跑步者模型,因为它没有被引用?我已经取出跑步者并尝试添加字段,但在 api 响应中我没有从跑步者那里获得任何数据。
  • 它在幕后被引用。 DRF 做了很多工作。当视图调用序列化程序时,它会传入查询集。您收到错误消息,还是没有收到任何数据?
  • @Neil 我不知道说实话。我通常不使用 DRF。我没有数据,也没有错误
  • 添加您的模型,以便我们帮助您设置视图集/序列化器

标签: python django django-rest-framework


【解决方案1】:

ViewSet 中的quesryset 包含Runner 实例:

queryset = Runner.objects.all()

但是在CombinedSerializer 中,您已经包含了runner 字段(映射到RunnerSerailizer)——您已经有一个Runner 模型实例,所以您没有runner 字段,您只有Runner 模型中可用的字段、任何反向相关的字段以及您在序列化程序上添加的自定义字段。


你有几个选择:

ModelSerializer继承并包含所有字段:

class CombinedSerializer(serializers.ModelSerializer):
    event = EventSerializer()
    market = MarketSerializer()

    class Meta:
        model = Runner
        fields = '__all__'

或者,如果您想对字段进行更精细的控制,请明确提及字段(在这种情况下,您可以保留 Serializer 继承)例如:

class CombinedSerializer(serializers.Serializer):
    event = EventSerializer()
    market = MarketSerializer()

    class Meta:
        fields = ('event', 'market', 'name', 'back_odds')

如果要从serializers.ModelSerializer继承,需要在Meta类中提及模型:

class CombinedSerializer(serializers.ModelSerializer):
    event = EventSerializer()
    market = MarketSerializer()

    class Meta:
        model = Runner
        fields = ('event', 'market', 'name', 'back_odds')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-06
    • 1970-01-01
    • 2016-09-11
    • 2014-05-31
    • 2016-08-06
    • 1970-01-01
    • 1970-01-01
    • 2013-04-08
    相关资源
    最近更新 更多