Django Rest Framework - Filter by relationship hyperlink

Viewed 91

I hope you are well. This is my first personal project with DRF and I had the following problem. I have two models:

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

and

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)
    ...

I was able to do something similar to what I need using 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',]

But this is what I get using the endpoint 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/"
    ]
},

I get a list with several links to Subareas, however I need only 1 link that lists all Subareas related to this Area, for example:

/api/area/1/subarea

endpoint that would list all subareas in area 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"
    ]
},

how can i do this using the DRF?

these are my views.py:

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

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

these are my 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)),
1 Answers

To get a single link to the list of children instead of a list of links to the children themselves, you should replace the use of HyperlinkedRelatedField with HyperlinkedIdentityField.

According to official docs:

HyperlinkedRelatedField

This serializer will give you a representation like this:

{
    '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/',
        ...
    ]
}

HyperlinkedIdentityField

This serializer will give you a representation like this:

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