首页 > 解决方案 > Django Rest Framework - 按关系超链接过滤

问题描述

我希望你一切都好。这是我与 DRF 的第一个个人项目,我遇到了以下问题。我有两个模型:

class Area(models.Model):
    name = models.CharField(max_length=100)
    ...

class SubArea(models.Model):
    area = models.ForeignKey("Area", on_delete=models.CASCADE, verbose_name='Area relacionada', 
    related_name='subareas')
    name = models.CharField(max_length=100)
    ...

我能够使用 HyperlinkedRelatedField 做类似于我需要的事情

class SubareaSerializer(serializers.ModelSerializer):
    contents = ContentSerializer(many=True, read_only=True)

    quizzes = QuizSerializerAux(many=True, read_only=True)
    class Meta:
        model = SubArea
        fields = ['id', 'name', 'description', 'quizzes', 'contents']


class AreaSerializer(serializers.HyperlinkedModelSerializer):

    subareas = serializers.HyperlinkedRelatedField(
        many=True,
        read_only=True,
        view_name='subarea-detail',
        )
    class Meta:
        model = Area
        fields = ['url','id', 'name', 'description', 'subareas',]

但这是我使用端点 api/area/ 得到的:

{
    "url": "http://127.0.0.1:8000/rest-auth/quiz/area/1/",
    "id": 1,
    "name": "Area 1 de teste",
    "description": "Area 1 de teste - descrição",
    "subareas": [
        "http://127.0.0.1:8000/rest-auth/quiz/subarea/1/",
        "http://127.0.0.1:8000/rest-auth/quiz/subarea/2/"
    ]
},

我得到一个包含多个子区域链接的列表,但是我只需要一个链接来列出与该区域相关的所有子区域,例如:

/api/area/1/子区域

将列出区域 id = 1 中所有子区域的端点

{
    "url": "http://127.0.0.1:8000/rest-auth/quiz/area/1/",
    "id": 1,
    "name": "Area 1 de teste",
    "description": "Area 1 de teste - descrição",
    "subareas": [
        "http://127.0.0.1:8000/rest-auth/quiz/area/1/subarea"
    ]
},

我怎样才能使用 DRF 做到这一点?

这些是我的views.py:

class AreaViewSet(viewsets.ModelViewSet):
    queryset = Area.objects.all()
    serializer_class = AreaSerializer

class SubareaViewSet(viewsets.ModelViewSet):
    queryset = SubArea.objects.all()
    serializer_class = SubareaSerializer

这些是我的 urls.py

router_quiz = routers.DefaultRouter()
router_quiz.register(r'area', AreaViewSet)
router_quiz.register(r'subarea', SubareaViewSet)
...
path('rest-auth/quiz/', include(router_quiz.urls)),

标签: pythondjangodjango-rest-framework

解决方案


要获得指向子列表的单个链接而不是指向子本身的链接列表,您应该替换使用HyperlinkedRelatedFieldwith HyperlinkedIdentityField

根据官方文档:

超链接相关字段

此序列化程序将为您提供如下表示:

{
    'album_name': 'Graceland',
    'artist': 'Paul Simon',
    'tracks': [
        'http://www.example.com/api/tracks/45/',
        'http://www.example.com/api/tracks/46/',
        'http://www.example.com/api/tracks/47/',
        ...
    ]
}

超链接身份字段

此序列化程序将为您提供如下表示:

{
    'album_name': 'The Eraser',
    'artist': 'Thom Yorke',
    'track_listing': 'http://www.example.com/api/track_list/12/',
}

推荐阅读