user3449833
user3449833

Reputation: 809

Django DRF More Detail After Fetching Object

New to DRF (and REST in general).

Models:

class Event(models.Model):
    name = models.CharField()

class Result(models.Model):
    event = models.ForeignKey(Event, related_name='results')
    person = models.CharField()
    score = models.IntegerField()

Serializers:

class ResultSerializer(serializers.ModelSerializer):
    class Meta:
            model = Result

class EventSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
            model = Event

Viewsets:

class ResultViewSet(viewsets.ModelViewSet):
    queryset = Result.objects.all()
    serializer_class = ResultSerializer

class EventViewSet(viewsets.ModelViewSet):
    queryset = Event.objects.all()
    serializer_class = EventSerializer

Router:

router = routers.DefaultRouter()
router.register(r'events', EventViewSet)

URL:

urlpatterns = [
    url(r'^api/', include(router.urls)),
]

This works fine, I can go to http://mysite/api and see "events" with a link to http://mysite/api/events/. From there each event has a link to http://mysite/api/events/id. So far so good.

If I change the event serializer to this, it will also include all the results (for that event) from Result:

class EventSerializer(serializers.HyperlinkedModelSerializer):
    results = ResultSerializer(many=True, read_only=True)
    class Meta:
            model = Event

This also works fine. But I don't want the (often very long) results to be included for each event at http://mysite/api/events. There are way too many. I'd only like to see results included when I go to http://mysite/api/events/id.

Any tips on how I can get from where I am to where I want to be? It would be even better if each item on http://mysite/api/events included a count of the results, then http://mysite/api/events/id actually had the results.

Hope this made sense. Thanks.

Upvotes: 1

Views: 46

Answers (1)

Rahul Gupta
Rahul Gupta

Reputation: 47846

We can create 2 serializers EventSerializer and EventDetailSerializer which will return different serialized representations based on the type of request.

class EventSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Event

class EventDetailSerializer(serializers.HyperlinkedModelSerializer):
    results = ResultSerializer(many=True, read_only=True) # contain the serialized results
    class Meta:
        model = Event

Then we will override the get_serializer_class() of EventViewSet which return EventDetailSerializer in case of retrieve requests and EventSerializer otherwise.

class EventViewSet(viewsets.ModelViewSet):
    queryset = Event.objects.all()

    def get_serializer_class(self):
        if self.action == 'retrieve': # check if a 'retrieve' request
            return EventDetailSerializer 
        return EventSerializer # otherwise return this serializer

Upvotes: 1

Related Questions