Abdulla Salimov
Abdulla Salimov

Reputation: 149

How to return custom JSON response in DRF?

I have created API for News model:

models.py

class News(models.Model):
    title = models.CharField(max_length=255)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title

serializers.py

class NewsSerializer(serializers.ModelSerializer):
    class Meta:
        model = News
        fields = [
            "id",
            "title",
            "created_at",
        ]

views.py

class NewsViewSet(ModelViewSet):
    serializer_class = NewsSerializer
    queryset = News.objects.all()

The current result of this API which is below:

[
    {
        "id": 1,
        "title": "testing1",
        "created_at": "2022-04-02T16:05:08.353708Z",
    }
]

And my question is there any ways to change the response format like below? I can not figure out how to make with Django DRF.

{
  "status": 0,
  "message": "Success",
  "data": {
    "updatedAt": "2020-08-31 17:49:15",
    "serverTime": "2022-03-23 15:10:11",
    "news": [
      {
        "id": 1,
        "title": "testing1",
        "created_at": "2022-04-02T16:05:08.353708Z",
      }
    ]
  }
}

Upvotes: 1

Views: 1510

Answers (2)

Evgeni Shudel
Evgeni Shudel

Reputation: 371

Consider another way:

class ResponseOptsMixin:

    def finalize_response(self, request, response, *args, **kwargs):
        response = super().finalize_response(request, response, *args, **kwargs)
        
        result_data = {
            "status": 0,
            "message": "Success",
            "data": {
                "updatedAt": "2020-08-31 17:49:15",
                "serverTime": "2022-03-23 15:10:11",
            },
        }
        model_name = self.queryset.model._meta.model_name
        result_data["data"][model_name] = response.data
        response.data = result_data

        return response


class NewsViewSet(ResponseOptsMixin, ModelViewSet):
    ...

Use this mixin wherever you needed

Upvotes: 0

Pradip Kachhadiya
Pradip Kachhadiya

Reputation: 2235

You can override list method in ModelViewSet to return custom response.

class NewsViewSet(ModelViewSet):
    serializer_class = NewsSerializer
    queryset = News.objects.all()

    def list(self, request, *args, **kwargs):
        # call the original 'list' to get the original response.
        response_data = super(NewsViewSet, self).list(request, *args, **kwargs)

        data = {
              "status": 0,
              "message": "Success",
              "data": {
                      "updatedAt": "2020-08-31 17:49:15",
                      "serverTime": "2022-03-23 15:10:11",
              "news": [{
                        "id": obj['id'],
                        "title": obj['title'],
                        "created_at": obj['created_at'],
                          } for obj in response_data.data]
                      }
            }

        return Response(data)

Upvotes: 3

Related Questions