1,DRF-序列化内容的准备-django的序列化-外键关系序列化以及反序列化-PATCH请求
https://www.cnblogs.com/GGGG-XXXX/articles/9258310.html --RSTful规范,
https://www.cnblogs.com/GGGG-XXXX/articles/9568816.html --DRF的序列化
https://www.cnblogs.com/wupeiqi/articles/7805382.html --restful规范,wusir
Django中间件跟版本有关系,不同的版本,执行,那几个中间件流程不一样,
csrf_token就放在prcess_view里面,
去请求体或者cookie中获取token,做校验,
api其实就是url,就是接口,
/
https://www.cnblogs.com/GGGG-XXXX/articles/9258310.html--RESTful rest:前后端交互的 一种规范, 前后端传输的是资源的表述,并不是资源的本身, rest 是面向资源的 soap是面向操作的 回调接口跟api接口是不一样的 执行.as_view()方法,自己没写,上view里面去找, as_view:return view view:return self.dispatch dispatch:return handler, 进行了请求方法的判断, json序列化不了queryset类型,序列化不了时间类型 JsonResponse可以序列化时间类型,但是序列化不了外键关系, 前端传过来的数据都会走序列化器进行反序列化, 并进行验证, serializers.py 序列化的时候放queryset,
/
many=True:序列化多个对象,就要写这个.如果是对象(get,first,last)就不用了,在外键那边,就是区分是多对多,而不是外键 序列化之后的数据是放在data里面的. source='get_category_display' #显示的是汉字了,不再是对应的数字了,(选择字段那个) required=False,就是反序列化的时候,字段不用进行校验,(前端传过来的数据) 正序: 后端的数据,需要序列化之后,给前端去展示, 反序列化: 前端提交的数据,也需要反序列化,转换成后端可以处理的数据格式, 反序是不走read_only=True,required=False的; 正序跟反序的时候字段类型不统一,导致,有的字段需要正序,有的需要反序; read_only=True,只正序的时候用(后端向前端传数据); write_only=True,只反序的时候用,(前端传数据给后端); post提交的数据: post提交的数据,不再是request.POST.get('xx')来获取了,而是在request.data,因为继承的类不一样了 save的时候,是调用的create的方法, put是全部更新, patch是局部更新 ser_obj = BookSerializer(instance=book_obj, data=request.data, partial=True) partial=True:是允许部分验证, save的时候,是调用的update的方法, post跟patch的区别-save的时候,调用的方法是不一样的. instance就是根据条件获取到的对象.(例如id=4)
/
postman伪造发各种请求,
http://127.0.0.1:8000/students/
RESTful REST风格 设计原则和约束条件 -- 资源 -- 统一资源定位符 URL 统一资源标识符 URI -- 统一资源的接口 -- 根据HTTP请求方式的不同对资源进行不同的操作 -- 前后端传输的是资源的表述 -- 页面展现的资源的状态 -- 超链接的指引来告诉用户接下来有哪些状态可以进去 RESTful架构 10条 -- 核心思想 -- 面向资源去编程 url中尽量用名词 -- 根据HTTP请求方式的不同对资源进行不同的操作 -- url体现 -- 版本 -- api -- 过滤条件?page=1 -- 尽量用https -- 返回 -- 携带状态码 -- 返回值 -- get 返回查询的所有或者单条数据 -- post 返回值新增的那条数据 -- put/patch 返回更新的那条数据 -- delete 空 -- 返回携带错误信息 -- 携带超链接 FBV和CBV的区别 -- def dispatch(self, request, *args, **kwargs): # Try to dispatch to the right method; if a method doesn't exist, # defer to the error handler. Also defer to the error handler if the # request method isn't on the approved list. # GET POST -- get post # self.get self.post # 判断你的请求方式是否在允许的http请求方式里 # 如果合法 self.get if request.method.lower() in self.http_method_names: handler = getattr(self, request.method.lower(), self.http_method_not_allowed) else: handler = self.http_method_not_allowed return handler(request, *args, **kwargs) 主要内容: json 轻量级的数据交互格式 -- Python --- json 序列化 -- json --- Python 反序列化 Django实现的序列化 -- .values 和JsonResponse -- 自己去构建想要的数据结构 -- django的 serialize -- 废话太多 外键关系依然需要自己去构建 DRF框架 -- 下载 -- pip install djangorestframework -- 在settings里注册app -- “rest_framework” DRF序列化 -- 声明一个序列化器 from rest_framework import serializers class BookSerializer(serializers.Serializer): # 这里声明想要序列化的字段 id = serializers.IntegerField() title = serializers.CharField(max_length=32) -- 视图 -- 视图类继承APIView -- 返回 Response -- ser_obj = BookSerializer(query_set, many=True) -- ser_obj.data DRF的反序列化 -- 序列化器 -- read_only -- write_only -- require=Flase -- 正序和反序列化的时候字段类型不同的时候 -- 重写create方法 -- ORM的操作进行新增数据 -- 视图 -- def post(self, request): book_obj = request.data print(request.data) ser_obj = BookSerializer(data=book_obj) if ser_obj.is_valid(): print(ser_obj.validated_data) ser_obj.save() return Response(ser_obj.validated_data) else: return Response(ser_obj.errors) DRF的更新操作 -- 序列化器 -- 写update方法 -- 视图 def patch(self, request, id): book_obj = Book.objects.filter(id=id).first() ser_obj = BookSerializer(instance=book_obj, data=request.data, partial=True) if ser_obj.is_valid(): ser_obj.save() return Response(ser_obj.validated_data) else: return Response(ser_obj.errors)
需要引入的,
from django.shortcuts import render from django.views import View from django.http import HttpResponse, JsonResponse from .models import Book, Publisher from django.core import serializers import json from rest_framework.views import APIView #view里需要引入的, from rest_framework.response import Response from .serializers import BookSerializer from rest_framework import serializers #在自定义的序列化器里,需要引入的,
需要注册app,不注册会报错,
json不是语言就是格式,
/
/
python与json可以转化的数据类型
/
/
拿django写接口,
引入的区别,
对比两者引入的区别,
from django.shortcuts import render,HttpResponse
from django.http import JsonResponse
HttpResponse与JsonResponse的区别,
JsonResponse就是继承的HttpResponse,JsonResponse,有封装了对时间的序列化方法,
使用DRF框架进行序列化,步骤,
第一步 下载 pip install djangorestframework
第二步 在settings注册一个app “rest_framework”
第三步 新建一个py文件,声明一个序列化器
第四步,在视图函数里面引入第三步的py文件,
JsonResponse 的使用
from django.shortcuts import render from django.views import View from django.http import HttpResponse, JsonResponse from app01 import models import json def login(request): book=models.Book.objects.all() print(book,book[0]) book_lst=models.Book.objects.all().values('id','title','put_time') #json不能序列化queryset的类型,需要强制类型转换一下, book_lst=list(book_lst) #safe=False,保证不报错,ensure_ascii保证可以是汉字 return JsonResponse(book_lst,safe=False,json_dumps_params={'ensure_ascii':False})
/
/
/
第一版:
把出版社封装成一个字典
def login(request): book=models.Book.objects.all() print(book,book[0]) book_lst=models.Book.objects.all().values('id','title','put_time','publisher') book_lst = list(book_lst) #有无下面for循环的区别 for book in book_lst: pub=Publisher.objects.filter(id=book['publisher']).first() book['publisher']={ 'id':pub.id, 'title':pub.title } return JsonResponse(book_lst,safe=False,json_dumps_params={'ensure_ascii':False})
//
第二版
用django的serialize方法实现的序列化,可以序列化queryset,依然不能序列化外键关系
#第二版 用django的serialize方法实现的序列化,数据冗余, from django.core import serializers def login(request): book_list=Book.objects.all() ret=serializers.serialize('json',book_list,ensure_ascii=False) return HttpResponse(ret)
显示不够友好,不是想要的,
第三版:使用DRF,需要先下载安装
https://blog.csdn.net/HH2030/article/details/81009071
代码
#view里的代码
from rest_framework.views import APIView from rest_framework.response import Response # 注意返回的时候,返回的数据,返回的 是Response了, from .serializers import BookSerializer
注意,此处继承的是APIView
class BookAPIView(APIView): def get(self,request): book_list=Book.objects.all() #many=True,表示序列化多个字段,要是单个的对象,就不用many=True了, ser_obj=BookSerializer(book_list,many=True) #序列化成功的数据是在ser_obj.data里面, return Response(ser_obj.data)
///
序列化器里面的代码
from rest_framework import serializers class PublisherSerializer(serializers.Serializer): id=serializers.IntegerField() title=serializers.CharField(max_length=32) class AuthorSerializer(serializers.Serializer): id=serializers.IntegerField() name=serializers.CharField(max_length=32) class BookSerializer(serializers.Serializer): # 变量名称要跟models里面的字段名称一致, id=serializers.IntegerField() title=serializers.CharField(max_length=32) #source='get_category_display' 获取到分类的中文,可以跟ORM的各种操作, category=serializers.CharField(max_length=32,source='get_category_display') put_time=serializers.DateField() #序列化外键关系,此处写的是定义的类名,PublisherSerializer,,, publisher=PublisherSerializer() #many=True用来表名序列化的是多对多的关系, authors=AuthorSerializer(many=True)
/
/
/
read_onlly与write_only的区别,
read_only是正序
反序是不走read_only=True,required=False ,
参考内容:https://blog.csdn.net/l_vip/article/details/79156113
提交的post进行save的时候,需要调用create方法,create写在自己创建的那个序列化器里面,
/
/
正序与反序的区别
/
前端传回的数据,
/
进行反序列化,构建前端传回的数据的数据格式,
/
提交成功,返回提交的信息,
/
创建数据
/
提交的数据与验证通过的数据,
/
错误信息的提示
/
patch 局部更新,调用的是update方法
patch进行局部更新,put进行全部更新,
restful规范
10条

1,使用https,安全,----------API与用户的通信协议,总是使用HTTPs协议。 2,域名 https://api.example.com 尽量将API部署在专用域名(会存在跨域问题) https://example.org/api/ API很简单, ---------------建议用这个, 3,版本 URL,如:https://api.example.com/v1/ -----用这个, 请求头 跨域时,引发发送多次请求 4,路径,视网络上任何东西都是资源,均使用名词表示(可复数)-------面向资源编程 https://api.example.com/v1/zoos https://api.example.com/v1/animals https://api.example.com/v1/employees 5,method GET :从服务器取出资源(一项或多项) POST :在服务器新建一个资源 PUT :在服务器更新资源(客户端提供改变后的完整资源) --------全部更新 PATCH :在服务器更新资源(客户端提供改变的属性) --------局部更新 DELETE :从服务器删除资源 6,过滤,通过在url上传参的形式传递搜索条件 https://api.example.com/v1/zoos?limit=10:指定返回记录的数量 https://api.example.com/v1/zoos?offset=10:指定返回记录的开始位置 https://api.example.com/v1/zoos?page=2&per_page=100:指定第几页,以及每页的记录数 https://api.example.com/v1/zoos?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序 https://api.example.com/v1/zoos?animal_type_id=1:指定筛选条件 7,状态码, 200 OK - [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)。 201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。 202 Accepted - [*]:表示一个请求已经进入后台排队(异步任务) 204 NO CONTENT - [DELETE]:用户删除数据成功。 301 永久重定向, 302 临时重定向, 400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等的。 401 Unauthorized - [*]:表示用户没有权限(令牌、用户名、密码错误)。 403 Forbidden - [*] 表示用户得到授权(与401错误相对),但是访问是被禁止的。 404 NOT FOUND - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的。 406 Not Acceptable - [GET]:用户请求的格式不可得(比如用户请求JSON格式,但是只有XML格式)。 410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到的。 422 Unprocesable entity - [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误。 500 INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。 简单认为:200系列是成功的,300系列是重定向的,400系列是客户端的错误,500系列是服务器端的错误 更多看这里:http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html 为什么要状态码:状态码是给用户做提示的, -----*****----***** 与前端交互,要状态码还是要code def get(requset): code={ 'code':1000, 'msg':'xxx' } return HttpResponse(json.dumps(code),status=201) 8,错误处理 错误处理,状态码是4xx时,应返回错误信息,error当做key。 { error: "Invalid API key" } 9,返回结果,针对不同操作,服务器向用户返回的结果应该符合以下规范。 GET /collection:返回资源对象的列表(数组) GET /collection/resource:返回单个资源对象 POST /collection:返回新生成的资源对象 PUT /collection/resource:返回完整的资源对象 PATCH /collection/resource:返回完整的资源对象 DELETE /collection/resource:返回一个空文档 10,Hypermedia API,RESTful API最好做到Hypermedia,即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么。 {"link": { "rel": "collection https://www.example.com/zoos", "href": "https://api.example.com/zoos", "title": "List of zoos", "type": "application/vnd.yourformat+json" }}
PublisherSerializer