Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using Django Rest framework to serialize custom data types and return response

Most of the tutorials on Django Rest Framework explains using the Django models and doing CRUD operations. That is a GET request on user model returns the attributes of user object in JSON format if I use JSON serializer.

I am designing my Django application to process a query and return response. For example, I provide a REST API to get the results of the following query

"Get me the user first name and department whose salary than XXX"

Here are my Django models:

class UserProfile(AbstractUser):
    age = models.PositiveIntegerField(_("age"))
    salary=models.PositiveIntegerField(_("salary"))

AUTH_USER_MODEL = "profiles.UserProfile"
User = get_user_model()

class Department(models.Model):
      users=models.ForeignKey(User)
      dept_name = models.CharField(max_length=30)

Now I have the following DTO (Data transfer object):

class CustomResponse(object):

def __init__(self, user_name, salary, dept_name):
      self.user_name = user_name
      self.salary = salary
      self.dept_name=dept_name

In my REST service implemented using DRF, I want the following

@api_view(['GET'])
def getNameandDept(salary):
    users=User.objects.filter(salary__gt=salary)
    toreturn=[]
    for user in users:
        response=CustomResponse(user.first_name,user.salary,user.dept_name)
        to_return.append(response)
    return Response(to_return)

I am not sure what is the right way to implement the above, with the tools that Django rest framework provide.

I am expecting the response something like this

[{user_name:"matt", salary:"5000", dept_name:"ENG"},{user_name:"smith",salary:"4000", dept_name:"HR"}....]

Thanks

EDIT

I was hoping DRF provides out of box tool for this kind of serialization. I have been using JAX-RS API (jersey and RESTeasy) that does this serialization.

like image 493
brain storm Avatar asked Feb 04 '15 05:02

brain storm


People also ask

How do you serialize an object in Django REST framework?

Creating and Using Serializers To create a basic serializer one needs to import serializers class from rest_framework and define fields for a serializer just like creating a form or model in Django.

What is serialization in Django REST framework?

Serializers allow complex data such as querysets and model instances to be converted to native Python datatypes that can then be easily rendered into JSON , XML or other content types.

When using a TemplateHTMLRenderer the data passed to the response should be serialized?

TemplateHTMLRenderer. Renders data to HTML, using Django's standard template rendering. Unlike other renderers, the data passed to the Response does not need to be serialized.

How do you pass extra context data to Serializers in Django REST framework?

In function based views we can pass extra context to serializer with "context" parameter with a dictionary. To access the extra context data inside the serializer we can simply access it with "self. context". From example, to get "exclude_email_list" we just used code 'exclude_email_list = self.


1 Answers

You don't really need the REST Framework for this. All you need is to define a serializer class instead of the CustomResponse that you have.

in serializers.py

from django.core.serializers.json import Serializer

class UserSerializer(Serializer):
    def get_dump_object(self, obj):
        mapped_object = {
            'user_name': obj.first_name,
            'salary': obj.salary,
            'dept_name': obj.dept_name
        }

        return mapped_object

then in your views.py

from myapp.serializers import UserSerializer

def getNameandDept(request, salary):
    users = User.objects.filter(salary__gt=salary)
    serializer = UserSerializer()
    return HttpResponse(serializer.serialize(users), mimetype='application/json')

Don't forget to define the salary argument in your urls.py

url(r'^users/(?P<salary>\d+)$', views.getNameandDept, name='getNameandDept'),

PS. You absolutely can do this with the DRF as well. It is a basic GET call (the filtering by salary has no effect on the serializer), so all you need to do there is define a ModelSerializer subclass with just the three fields

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('first_name', 'salary', 'dept_name')

and then serialize the output (note the slightly different syntax)

serializer = UserSerializer(users)
return Response(serializer.data)
like image 110
Martin B. Avatar answered Nov 03 '22 13:11

Martin B.