Serializer

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

编写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.validaated_data.get()获取post数据参数.注意,只能获取到serializer类中定义的字段值.在该例子中,name和code在TestSerializer中有定义,当post参数名为那么和code时可以获取,否则不能获取.比如,当post有个参数是username时,使用serializer.validated_data.get("username","")不能得到username的参数值.

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即可.

Django的Serializers的使用的更多相关文章

  1. django序列化 serializers

    Django的序列化工具让你可以将Django的模型‘翻译’成其它格式的数据.通常情况下,这种其它格式的数据是基于文本的,并且用于数据交换\传输过程. 一.序列化数据 Django为我们提供了一个强大 ...

  2. django restframework Serializers

    序列化器允许将诸如查询集和模型实例之类的复杂数据转换为原生 Python 数据类型,然后可以将它们轻松地呈现为 JSON,XML 或其他内容类型.序列化器还提供反序列化,在首次验证传入数据之后,可以将 ...

  3. django rest_framework Serializers 序列化组件

    为什么要用序列化组件 当我们做前后端分离的项目~~我们前后端交互一般都选择JSON数据格式,JSON是一个轻量级的数据交互格式. 那么我们给前端数据的时候都要转成json格式,那就需要对我们从数据库拿 ...

  4. django的serializers

    views.py # get所需的 from snippets.serializers import SnippetSerializer from rest_framework.views impor ...

  5. Django的serializers使用

    Serializer 在这里通过一个验证用户身份的例子说明rest_framework中serializer.Serializer的使用. 编写serializer Serializer的使用不需要依 ...

  6. 第六章:Django 综合篇 - 9:序列化 serializers

    Django的序列化工具让你可以将Django的模型'翻译'成其它格式的数据.通常情况下,这种其它格式的数据是基于文本的,并且用于数据交换\传输过程. 一.序列化数据 Django为我们提供了一个强大 ...

  7. Django REST framework+Vue 打造生鲜超市(四)

    五.商品列表页 5.1.django的view实现商品列表页 (1)goods/view_base.py 在goods文件夹下面新建view_base.py,为了区分django和django res ...

  8. Django中Q搜索的简单应用

    本节涉及: 1.Q搜索在前后端的设计 2.Django中Queryset对象的序列化(由后端扔给前端的数据必然会经过序列化) 3.前端动态地构造表格以便显示(动态创建DOM对象) 思路: 用户通过前端 ...

  9. Django知识总结(三)

    拾伍 ● Ajax技术 一 ● Ajax定义 Ajax: 异步的 JavaScript 和 XML (Asynchronous+Javascript+XML) 通过Ajax, 我们可以在不重新加载整个 ...

随机推荐

  1. p2071 座位安排

    传送门 题目 已知车上有N排座位,有N*2个人参加省赛,每排座位只能坐两人,且每个人都有自己想坐的排数,问最多使多少人坐到自己想坐的位置. 输入格式: 第一行,一个正整数N. 第二行至第N*2+1行, ...

  2. try catch 块中debug时发现错误细节的一次记录

    在解决已有代码的一个问题时,有一个try catch块,基本代码如下: try { //do something } catch { LogHelper.Debug(typeof(myHelper), ...

  3. 20. Linux提权:从入门到放弃

    几点前提 已经拿到低权shell 被入侵的机器上面有nc,python,perl等linux非常常见的工具 有权限上传文件和下载文件 内核漏洞提权 提到脏牛,运维流下两行眼泪,我们留下两行鼻血.内核漏 ...

  4. Ruby and gnuplot installation on Ubuntu 16.04

    sudo apt install ruby gnuplot

  5. Selenium2.0+TestNG+Ant+Jenkins自动化测试浅尝

    当前常用自动化测试工具 Web自动化测试工具:QTP .selenium等 性能自动化测试工具:loadrunner.jmeter等 接口自动化测试工具:SoapUI.postman等 手机自动化测试 ...

  6. js默认事件汇总

    默认事件 就是浏览器通过HTML标签或DOM元素提供的一些功能性的默认行为.比如在a标签href属性上的跳转,右键呼出的菜单等等.我们可以通过js取消或更改这些默认事件. 取消默认事件 默认事件都是定 ...

  7. SQL语法:MySQL系列之四

    一.SQL语言的简介和规范 ​ 是一种特定目的程序语言,用于管理关系数据库管理系统(RDBMS),或在关系流数据管理系统(RDSMS)中进行流处理. 20世纪70年代,IBM开发出SQL,用于DB2 ...

  8. AT2160 へんなコンパス / Manhattan Compass

    传送门 乍一看像是一个计算几何,然后想到了BFS,但是苦于无奈\(O(n^2)\)不会优化 然后以下参考zjq_shadow大佬的思路 显然发现曼哈顿距离很麻烦,除了暴力枚举貌似没什么很好的办法 考虑 ...

  9. thinkphp实现登录后返回原界面

    主要思路还是用session记录原地址,在登录后再跳转回原界面 先保存请求login方法界面的url public function savelogin(){ session('returnUrl', ...

  10. 模型事件注意点,before_delete、after_delete、before_write、after_write、before_update、after_update、before_insert、after_insert

    模型类支持before_delete.after_delete.before_write.after_write.before_update.after_update.before_insert.af ...