一、后端发送列表、字典
1. 发送字典出现safe error,需要如下处理
def books(request): ll=[{'name':'python全站开发','price':20},{'name':'linux','price':30}] # return HttpResponse(json.dumps(ll)) return JsonResponse(ll,safe=False,json_dumps_params={'ensure_ascii':False})
2. 发送列表,不能直接json.dumps了,需要加json_dumps_params属性了,如上
二、 request获取get.post数据
1. 现在reques.request都是用的'.'属性拦截方法,有属性的话取值,没有的话则获取__getattr__的值
2.request.get
3.request.method
4.request.data (支持urlencoded,form-data,json格式的数据),postman模拟 -------> 取代request.POST(只支持urlencoded,form-data格式的数据)
from rest_framework.views import APIView class Book(APIView): def get(self,request): # 拿原来的request对象 # request._request # print(request.method) # print(request._request.method) # request.POST # request.method return HttpResponse('get') def post(self,request): print(request.method) print(request._request.method) print(request.POST) # 用apiview之后,再取数据,从request.data print(request.data) return HttpResponse('post')
三、序列化组件
三种方式
from app01 import models 序列化组建 第一种方式 class Book(APIView): def get(self,request): response={'status':100,'msg':None} books=models.Book.objects.all() # ll=[] # for book in books: # ll.append({'name':book.name,''}) ll=[ {'name':book.name,'price':book.price} for book in books] response['msg']='查询成功' response['data']=ll return JsonResponse(response,safe=False) # return HttpResponse('get') def post(self,request): return HttpResponse('post') 第二种方式,用django子自带序列化组件 from django.core import serializers # class Book(APIView): # def get(self,request): # # response={'status':100,'msg':None} # books = models.Book.objects.all() # ret = serializers.serialize("json", books) # return HttpResponse(ret) # # # return HttpResponse('get') # def post(self,request): # # return HttpResponse('post') # 第三种方式。drf的序列化组件 class MyResponse(): def __init__(self): self.status = 100 self.msg = None @property def get_dic(self): return self.__dict__
from app01 import myserial
class Book(APIVIEW):
def get(self,request):
response = MyResponse()
# 多条
books = models.Book.objects.all()
ret=myserial.BookSer(books,many=True)
# 一条
book = self.queryset
ret = myserial.BookSer(book, many=False)
ret = self.serializer_class(instance=book, many=True)
response.msg = '查询成功'
response.data = ret.data
return Jsonponse(response.get_dic,safe=False)
myserial.py
from rest_framework import serializers class BookSer(serializers.Serializer): nid=serializers.IntegerField() name3=serializers.CharField(source='name') price=serializers.CharField() # publish_date = serializers.DateField() publish_date = serializers.CharField() # publish=serializers.CharField(source='publish.email') publish=serializers.CharField(source='publish.name') xxx=serializers.CharField(source='test') # authors=serializers.CharField(source='authors.all') # SerializerMethodField,可以写一个方法方法名叫:get_字段名字,方法返回值,会赋给authors aa=serializers.SerializerMethodField() # def get_authors(self,obj): # authors=obj.authors.all() # # ll=[ author.name for author in authors] # ll=[ {'name':author.name,'age':author.age} for author in authors] # return ll def get_aa(self, obj): authors = obj.authors.all() # ll=[ author.name for author in authors] ser=AuthorSer(authors,many=True) return ser.data
class AuthorSer(serializers.Serializer):
id=serializers.IntegerField(source='nid')
age=serializers.CharField()
name=serializers.CharField()
总结
序列化组价涉及到多对多查询的处理和引用对象
一 restfu(规范) 是什么: -面向资源编程 -getBooklist:获取图书列表 -符合规范的:books 规范: -method:get----》books----》取到所有的书 post———》books---》新增图书 put/patch--》books/id---》修改图书 delete---》books/id---》删除图书 -https://api.example.com/v1/zoos?limit=10 - 二 drf 安装(app):pip3 install djangorestframework -基于drf写resful的接口,得写CBV -request对象,源码分析 -APIView源码分析 三 序列化组件 -1 导入:from rest_framework import serializers -2 写一个类(名字任意),继承serializers.Serializer class BookSer(serializers.Serializer): nid=serializers.IntegerField() name3=serializers.CharField(source='name') price=serializers.CharField() # publish_date = serializers.DateField() publish_date = serializers.CharField() # publish=serializers.CharField(source='publish.email') publish=serializers.CharField(source='publish.name') xxx=serializers.CharField(source='test') -3 如果不指定source,字段名,必须跟数据库列名一致 -4 source--》既可以指定数据属性,又可以指定方法属性,可以写(publish.name) -5 使用: -查询出要序列化的数据:books = models.Book.objects.all() -ret=myserial.BookSer(books,many=True)-----》多条(queryset对象),必须指定many=True -ret=myserial.BookSer(books,many=False)-----》一条(Book对象),必须指定many=False -6 aa=serializers.SerializerMethodField() -必须配套一个方法(get_aa(self,obj)),方法返回结果,会赋给aa -在方法内部,可以继续用序列化组件
四、序列化组件之serializers.ModelSerializer
1、使用
from app01 import models class BookSer(serializers.ModelSerializer): class Meta: # 指定要序列号的表模型是book model=models.Book # 把所有字段都序列化 # fields='__all__' # 可以传列表,指定取几个 # fields=['name','authors','publish'] # 除了nid都查 exclude=['authors'] #fields和exclude不能同时用 # depth指定深度,个人建议最多用3 # depth=2
2、ps
四 序列化组件之serializers.ModelSerializer -用法同Serializer -不同点: class BookSer(serializers.ModelSerializer): class Meta: # 指定要序列号的表模型是book model=models.Book fields='__all__' exclude=['nid'] depth=1
五 序列化组件的字段校验和反序列化功能
序列化组件可以将对象序列化成字典,也可以将字典反序列化成对象,调用save()方法,保存前台传过来的数据
-只有:ModelSerializer,能直接保存 - def post(self,request): print(request.data) #生成一个序列化对象 ser=myserial.BookSer(data=request.data) #判断字段是否校验通过 if ser.is_valid(): #通过,直接保存 ser.save() else: #错误信息 print(ser.errors) return HttpResponse('post')
使用
from app01 import models class BookSer(serializers.ModelSerializer): class Meta: # 指定要序列号的表模型是book model=models.Book # 把所有字段都序列化 fields='__all__' # 可以传列表,指定取几个 # fields=['name','authors','publish'] # 除了nid都查 exclude=['authors']