Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rename response fields django rest framework serializer

I'm calling a simple get API using djangorestframework. My Model is

class Category(models.Model):
    category_id = models.AutoField(primary_key=True)
    category_name = models.CharField("Category Name", max_length = 30)
    category_created_date = models.DateField(auto_now = True, auto_now_add=False)
    category_updated_date = models.DateField(auto_now = True, auto_now_add=False)

    def __str__(self):
        return self.category_name

serializer.py

class CategorySerializer(serializers.ModelSerializer) :
    class Meta:
        model = Category
        fields = ['category_id', 'category_name']

def category_list(request):
    if request.method == 'GET':
        categories = Category.objects.all()
        serializer = CategorySerializer(categories, many=True)
        return Response(serializer.data)

It's working fine when i hit request on the URL and returning following response.

[
    {
        "category_id": 1,
        "category_name": "ABC"
    }
]

i want to change the response field names as it's for my DB only and don't want to disclose in response. If i change the name in serializer class than it's giving no field match error.

Also i want to customise other params like above response in response object with message and status like below.

{
status : 200,
message : "Category List",
response : [
        {
            "id": 1,
            "name": "ABC"
        }
    ]
}

Need a proper guide and flow. Experts help.

like image 243
Pinank Lakhani Avatar asked Sep 05 '16 06:09

Pinank Lakhani


People also ask

What does serializer Is_valid () do?

The .is_valid() method takes an optional raise_exception flag that will cause it to raise a serializers.ValidationError exception if there are validation errors.

What is the difference between ModelSerializer and HyperlinkedModelSerializer?

The HyperlinkedModelSerializer class is similar to the ModelSerializer class except that it uses hyperlinks to represent relationships, rather than primary keys. By default the serializer will include a url field instead of a primary key field.

What is serializing in Django?

Django's serialization framework provides a mechanism for “translating” Django models into other formats. Usually these other formats will be text-based and used for sending Django data over a wire, but it's possible for a serializer to handle any format (text-based or not).


4 Answers

You can override to_representation function in serializer.Check the following code you can update data dictionary as you want.

class CategorySerializer(serializers.ModelSerializer) :
    class Meta:
        model = Category
        fields = ['category_id', 'category_name']
    def to_representation(self, instance):
        data = super(CategorySerializer, self).to_representation(instance)
        result_data={"status" : 200,"message" : "Category List"}
        result_data["response"]=data
        return result_data
like image 43
Himanshu dua Avatar answered Oct 22 '22 03:10

Himanshu dua


First of all using category_ in field names is redundant. Because you are already assigning this fields to Category model, and by doing this you are creating "namespace" for this fields.

class Category(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField("Category Name", max_length = 30)
    created_date = models.DateField(auto_now = True, auto_now_add=False)
    updated_date = models.DateField(auto_now = True, auto_now_add=False)

    def __str__(self):
        return self.name

Second In django id AutoField is created automatically why would you need set it explicitly?

And answering your question There is source parameter in serializer fields.

class CategorySerializer(serializers.ModelSerializer):
    renamed_id = serializers.IntegerField(source='category_id')
    renamed_name = serializers.CharField(source='category_name')

    class Meta:
        model = Category
        fields = ['renamed_id', 'renamed_name']

And than you can change your response manually

from rest_framework import status

def category_list(request):
    if request.method == 'GET':
        categories = Category.objects.all()
        serializer = CategorySerializer(categories, many=True)
        response = {
            'status': status.HTTP_200_OK,
            'message' : "Category List",
            'response' : serializer.data
        }
        return Response(response)
like image 175
Sardorbek Imomaliev Avatar answered Oct 22 '22 04:10

Sardorbek Imomaliev


You can just wrap it up in json. This is the way you render the way you want:

from django.http import HttpResponse
import json

def category_list(request):
    if request.method == 'GET':
        categories = Category.objects.all()
        serializer = CategorySerializer(categories, many=True)
        response = {'code: 200, 'message': 'Category List', 'response': serializer.data}
        return HttpResponse(json.dumps(response), mimetype='application/json')

This is the way you can rename your fields:

class CategorySerializer(serializers.ModelSerializer):
    name = serializers.CharField(source='category_name')

    class Meta:
        model = Category
        fields = ['category_id', 'name']

This is the docs for serializing with different names.

like image 2
vishes_shell Avatar answered Oct 22 '22 02:10

vishes_shell


In Django 2.1.1 if you are using a viewset, you can customize the other parts of your response by overriding the .list() action like this

from rest_framework import status
from django.http import HttpResponse
import json

class CategoryViewset(viewsets.ReadOnlyModelViewSet):
    categories = Category.objects.all()

    def list(self, request):
        if request.method == 'GET':
            serializer = CategorySerializer(self.categories, many=True)
            response = {
                'status': status.HTTP_200_OK,
                'message' : "Category List",
                'response' : serializer.data,
            }
            return HttpResponse(json.dumps(response), content_type='application/json')
like image 1
Jimmu Avatar answered Oct 22 '22 04:10

Jimmu