peter
peter

Reputation: 1582

DRF return serialized object in create() method

I'm writing a custom create method for my model:

class TripReportViewSet(viewsets.ModelViewSet):
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
    serializer_class = TripReportSerializer
    pagination_class = TripReportSetPagination
    # To order by favorite count or 'top':
    queryset = TripReport.objects.all().annotate(count=Count('favoriters')).order_by('-count')
    #queryset = TripReport.objects.all().order_by('-pk')
    filter_backends = (filters.SearchFilter, filters.OrderingFilter)
    search_fields = ('=author__username', '=slug', 'countries__name', )
    ordering_fields = ('pk', )

    def create(self, request, **kwargs):
        countries = request.POST['countries'].split(',')
        countries = list(map(int, countries))
        countries = Country.objects.filter(pk__in=countries)

        instance = TripReport.objects.create(
            author=User.objects.get(pk=request.POST['author']),
            title=request.POST['title'],
            content=request.POST['content'],
        )
        instance.countries.set(countries)
        instance.save()
        return HttpResponse(TripReportSerializer(instance))

I can't seem to get the right response. I want to return my serialized object, but

HttpResponse(instance)

and

HttpResponse(TripReportSerializer(instance))

is giving me the wrong result. TripReportSerializer is the one I'm using for the view.

Upvotes: 4

Views: 4176

Answers (2)

JPG
JPG

Reputation: 88659

What you have to do is, serialize the newly created Trip instance and return by using DRF's Response class

from rest_framework.response import Response


class TripReportViewSet(viewsets.ModelViewSet):
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
    serializer_class = TripReportSerializer
    pagination_class = TripReportSetPagination
    # To order by favorite count or 'top':
    queryset = TripReport.objects.all().annotate(count=Count('favoriters')).order_by('-count')
    # queryset = TripReport.objects.all().order_by('-pk')
    filter_backends = (filters.SearchFilter, filters.OrderingFilter)
    search_fields = ('=author__username', '=slug', 'countries__name',)
    ordering_fields = ('pk',)

    def create(self, request, **kwargs):
        countries = request.POST['countries'].split(',')
        countries = list(map(int, countries))
        countries = Country.objects.filter(pk__in=countries)

        instance = TripReport.objects.create(
            author=User.objects.get(pk=request.POST['author']),
            title=request.POST['title'],
            content=request.POST['content'],
        )
        instance.countries.set(countries)
        instance.save()
        # changes
        serializer = TripReportSerializer(instance)
        return Response(serializer.data)

Upvotes: 2

A. J. Parr
A. J. Parr

Reputation: 8026

I see two things wrong with the code:

  1. To return the serializer data I think you should use TripReportSerializer(instance).data
  2. Rest Framework Views generally return a Response object, which is imported from rest_framework.response.Response

Another amendment you should make is to use the views get_serializer() method so the serializer will be populated with the context (view, format, and request), which in your case would mean using this code at the end of your create method.

serializer = self.get_serializer(instance)
return Response(serializer.data)

Upvotes: 5

Related Questions