using Django Rest framework to serialize custom da

2019-07-06 14:18发布

问题:

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.

回答1:

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)