【问题标题】:Django rest: accessing all related objects using ForeignKeyDjango rest:使用 ForeignKey 访问所有相关对象
【发布时间】:2021-10-29 13:29:12
【问题描述】:

我被卡住了,我不知道出了什么问题……对我来说,这与 DRF API 指南中的“嵌套关系”示例相同,但有些地方不对……

型号

class PlayerSquadra(models.Model):
    
    player = models.ForeignKey(
       'app_player.Player',
       on_delete=models.CASCADE,
       verbose_name=_('giocatore'),
       related_name='player_squadraplayer',
    )

    squadra = models.ForeignKey(
        'app_stagione.Squadra',
        on_delete=models.CASCADE,
        verbose_name=_('squadra'),
        related_name='squadra_squadraplayer'
    )

    def __str__(self):
        return '%s' % (self.player)

网址

router.register(r'squadraJSON/(?P<squadra>.*)', views.SquadraViewSet)

查看

class SquadraViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Squadra.objects.all()
    serializer_class = SquadraSerializer

    def get_queryset(self):
        laSquadra = self.kwargs['squadra']
        queryset = Squadra.objects.filter(id=int(laSquadra))
        return queryset

序列化器

class PlayerSquadraSerializer(serializers.ModelSerializer):
    class Meta:
        model = PlayerSquadra
        fields = '__all__'

class SquadraSerializer(serializers.ModelSerializer):
    playersquadra = PlayerSquadraSerializer(many=True, read_only=True)

    class Meta:
        model = Squadra
        fields = ['nomeSquadra','id','playersquadra']

当我打电话给http://192.168.0.102:8000/squadraJSON/26/ 时,我得到的是:

GET /squadraJSON/26/
HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

[
    {
        "nomeSquadra": "prova2",
        "id": 26
    }
]

并且没有错误......虽然我期待这样的事情:

GET /squadraJSON/26/
HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

[
    {
        "nomeSquadra": "prova2",
        "id": 26
        "playersquadra": [
            {'id': 1, 'firstName': 'Michael', 'lastName': 'Jordan',...},
            {'id': 2, 'firstName': 'Larry', 'lastName': 'Bird',...},
            ...
        ],
    }
]

您能否给我一些提示,为什么我没有找到所有属于 Squadra 且 id=26 的玩家?感谢您的帮助

【问题讨论】:

    标签: python django django-models django-rest-framework foreign-keys


    【解决方案1】:

    你必须使用related_name来访问所有相关的PlayerSquadra,也就是squadra_squadraplayer,所以:

    class SquadraSerializer(serializers.ModelSerializer):
        playersquadra = PlayerSquadraSerializer(
            many=True, read_only=True, source='squadra_squadraplayer',
        )
    
        class Meta:
            model = Squadra
            fields = ['nomeSquadra','id','playersquadra']
    

    或:

    class SquadraSerializer(serializers.ModelSerializer):
        # This will change the name of the key to squadra_squadraplayer
        squadra_squadraplayer = PlayerSquadraSerializer(many=True, read_only=True)
    
        class Meta:
            model = Squadra
            fields = ['nomeSquadra','id','squadra_squadraplayer']
    

    甚至:

    class SquadraSerializer(serializers.ModelSerializer):
        playersquadra = serializers.SerializerMethodField()
    
        class Meta:
            model = Squadra
            fields = ['nomeSquadra','id','playersquadra']
        
        def get_playersquadra(self, obj):
            return PlayerSquadraSerializer(
                obj.squadra_squadraplayer, many=True, read_only=True,
            ).data
    

    【讨论】:

    • 感谢您的快速回答...只是评论:我尝试了第一个建议的解决方案并且有效,但是 DRF 文档中的 example 呢?它只是缺少源参数(因此纠正它可能很有用)并且它不能按原样工作还是我错过了什么?再次感谢您的帮助!
    • 它不需要源参数,因为字段名称(tracks)与来自albumstrackrelated_name 匹配:album = models.ForeignKey(Album, related_name='tracks', on_delete=models.CASCADE)
    • 这也显示在我的第二个示例中。 squadra_squadraplayer 匹配相关名称,因此无需定义 source。如果不清楚,请告诉我
    • 另一个例子是如果你想在序列化程序中使用playersquadra而不指定源,在PlayerSquadra模型中将squadra外键的相关名称从squadra_squadraplayer更改为playersquadra跨度>
    猜你喜欢
    • 1970-01-01
    • 2018-07-30
    • 2021-09-28
    • 2016-05-27
    • 2017-08-06
    • 2019-07-11
    • 2022-11-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多