Serializer

在这里通过一个验证用户身份的例子说明rest_framework中serializer.Serializer的使用。

编写serializer

Serializer的使用不需要依赖于模型,所以可以不要编写model,直接编写serializer文件。

from rest_framework import serializers

class TestSerializer(serializers.Serializer):

    name = serializers.CharField(max_length=20, required=True)
code = serializers.CharField(max_length=20, required=True)

编写view

使用rest_framework的APIView编写视图,实现get和post方法

from django.http import HttpResponse, JsonResponse
from django.contrib.auth import authenticate
from rest_framework import status
from rest_framework.views import APIView
from rest_framework.response import Response from school.serializers.school import TestSerializer class TestView(APIView): def get(self, request):
# 获取auth中的用户
user = request.user
if user.is_authenticated: # is_superuser
return HttpResponse(user.username + '已授权')
return HttpResponse('未授权') def post(self, request):
serializer = TestSerializer(data=request.data) if serializer.is_valid():
username = serializer.validated_data.get("name", "")
password = serializer.validated_data.get("code", "") # 调用authenticate方法
user = authenticate(username=username, password=password) if user is not None:
content = {
"status": True,
"message": "账户正确"
}
return JsonResponse(data=content, status=status.HTTP_200_OK)
else:
content = {
"status": False,
"message": "账号或者密码不正确"
}
return JsonResponse(data=content, status=status.HTTP_200_OK)
else:
return Response(data=serializer.errors)

使用django的View和rest_framework的APIView实现get和post方法时,无论是否显式使用到request,都需要request参数,否则会出错。

get

  • 首先通过request.user获取auth信息
  • 然后根据is_authenticated或is_superuser等判断auth信息是否符合要求。auth的用户名和密码可以通过request.user.username和request.user.password获取。

post

在前面的get方法中并未用到serializer,只是获取了auth信息。而在post方法中将serializer结合post参数验证user信息。

  • 首先,通过post的参数创建一个序列化类实例。
  • 然后,判断序列化实例是否有效,无效则直接返回序列化错误信息
  • 当序列化有效时,通过serializer.validated_data.get()获取post数据参数。注意,只能获取到serializer类中定义的字段值。在该例子中,name和code在TestSerializer中有定义,当post参数名为name和code时可以获取,否则不能获取。比如,当post有个参数是username时,使用serializer.validated_data.get("username", "")不能得到username的参数值。
  • 最后使用authenticate验证,根据验证结果返回相关信息。

ModelSerializer

ModelSerializer的使用需要依赖于已有model模型,常用来编写api。这里只介绍ModelSerializer的使用,view方面不作说明。

创建模型

首先需要创建模型,这里拿一个外键关联的例子来说明。

from django.db import models

class School(models.Model):
name = models.CharField(max_length=32, verbose_name="名称")
code = models.CharField(max_length=16, verbose_name="代码")
location = models.CharField(max_length=128, verbose_name="地址") class Student(models.Model):
name = models.CharField(max_length=32, verbose_name="姓名")
age = models.IntegerField(verbose_name="年龄")
school = models.ForeignKey(to=School,verbose_name="学校", on_delete=models.CASCADE)

这里,有两个模型,Student模型通过school字段关联School模型,on_delete=models.CASCADE表示删除School实例时会级联删除Student实例。

序列化

由于School只有三个基本类型字段,所以这里以Student的序列化为例进行说明。

# -*- coding: utf-8 -*-
from rest_framework import serializers from school.models import Student, School class StudentSerializer(serializers.ModelSerializer):
# 多对多时添加参数 many=True
school = serializers.SlugRelatedField(read_only=False, slug_field="name", queryset=School.objects.all())
# address = serializers.CharField(source="school.address", default=None) def create(self, validated_data):
# some actions
instance = super().create(validated_data)
return instance def update(self, instance, validated_data):
user = self.context['request'].user # 请求的用户
username = self.context['request'].data.get('username') # 请求的参数username
instance.name = validated_data['name'] # 请求的参数name
# some actions
instance.save()
return instance class Meta:
model = Student
fields = ('id', 'name', 'age', 'school')
read_only_fields = ('id', 'age')

在这里值得注意的地方主要有三点:序列化外键字段、重写create方法、重写update方法。

  • 在序列化外键字段时,如果要使用被关联对象的某个字段来代表该字段,可以使用SlugRelatedField。在多对多情况下还需要添加参数many=True。当然,也可以另起一个字段来展示被关联对象某个字段的值,如
address = serializers.CharField(source="school.address", default=None)

除了上面的方法,还可以使用一个更通用的方法,可以序列化非模型中的字段或者外键的外键等。

使用SerializerMethodField通过定义方法序列化:

status = serializers.SerializerMethodField()

def get_status_verbose(self, obj):
# obj表示当前模型对象
return obj.get_status_display()
  • 重写create方法有两个参数,validated_data中是创建实例各字段的值,调用super().create(validated_data)即创建了实例,返回实例对象instance。我们可以在调用父类的create方法前后作一些处理,比如在调用之前对validated_data中的字段重新赋值。当在创建实例时,如果需要附带自动创建日志实例时,可以将instance作为日志实例的外键创建日志实例。最后将创建的Student实例instance返回出去。

  • 重写update方法有三个参数,instance是要修改的模型实例,validated_data是请求的参数。在update方法中,我们一般需要获取相关的数据来修改模型的值,主要可以归为三种。第一,获取用户信息,使用self.context['request'].user。第二,请求参数中的数据,但是参数的名称与模型字段的名称不一致,无法通过validated_data获取,使用self.context['request'].data.get('username')获取。第三,请求参数中与模型字段命名一致的数据,直接使用validated_data['name']获取。获取完数据后可以对instance的字段进行一些赋值操作,最后保存instance即可。

最新文章

  1. Introduction to Microsoft Dynamics 365 licensing
  2. 以libfuse为例介绍rpm打包工具rpmbuild的使用和SPEC文件的编写
  3. 欢迎来到vmax-tam的博客
  4. JS each 跳出
  5. poj 1348 Computing (四个数的加减乘除四则运算)
  6. 我们说的oc是动态运行时语言是什么意思?
  7. Win7设置局域网共享
  8. Hibernate(五):Hibernate配置文件及C3P0的用法
  9. 【python】闭包
  10. docker服务各个模块
  11. Swift 拷贝文件夹,实现文件夹内容整体复制
  12. 解决AJAX应用,会话超时(Session Timeout)的问题,粗略方法(不考虑使用Filter的前提下)
  13. MSOCache office问题
  14. flask-日料网站搭建-ajax传值+返回json字符串
  15. c++刷题(18/100)树
  16. linux创建新用户
  17. SQL SERVER2014的安装
  18. 自定义控件如何给特殊类型的属性添加默认值 z(转)
  19. Linux文件上传下载sz 和 rz 命令
  20. ASP.NET Visual Studio2010 发布Web网站问题详解

热门文章

  1. js+css实现简单下拉菜单
  2. svn上传文件钩子
  3. ZOJ - 3201 Tree of Tree (树形背包)
  4. 转载:maven依赖范围
  5. 461. Hamming Distance Add to List
  6. Linux下anaconda的安装
  7. SQL夯实基础(五):索引的数据结构
  8. 【LeetCode】075. Sort Colors
  9. c#生成唯一编号方法记录,可用数据库主键 唯一+有序
  10. Linux 优秀软件