本文共 8412 字,大约阅读时间需要 28 分钟。
API就是接口,提供的url。接口有两个用途:
网络应用程序,分为前端和后端两个部分。当前的发展趋势,就是前端设备层出不穷(手机、平板、桌面电脑、其他专用设备......)。
因此,必须有一种统一的机制,方便不同的前端设备与后端进行通信。这导致API构架的流行,甚至出现的设计思想。是目前比较成熟的一套互联网应用程序的API设计理论。
127.0.0.1:8000/books //查127.0.0.1:8000/books/add //增127.0.0.1:8000/books/change/1 //改127.0.0.1:8000/books/delete/1 //删
GET请求查看数据:127.0.0.1:8000/books 返回所有数据列表 :[{}, {}, {}]GET请求查看单条数据:127.0.0.1:8000/books/1 返回查看的单条数据{}POST请求添加数据:127.0.0.1:8000/books 返回添加数据 :{}PUT请求更新pk = 1的数据:127.0.0.1:8000/books/1 返回更新后的数据: {}Delete请求删除pk = 1的数据:127.0.0.1:8000/books/1 返回空
pip3 install djangorestframework
APIView的源码执行可以参考DjangoCBV的源码执行逻辑
对请求的数据进行解析:是针对请求体进行解析的。表示服务器可以解析的数据格式的种类
Content-Type: application/url-encoding..... //数据格式
request.body # 请求体中的原生数据 request.POSTContent-Type: application/json..... //数据格式
request.body # 请求体中的原生数据 request.POST这种情况下每次都要decode(解码),loads(反序列化),真的很麻烦,所以才有的解析器组件。弥补了django的缺点。
parser_classes = [JSONParser/FormParser/....] #表示服务器可以解析的数据格式的种类
需要用什么数据格式就添加什么数据格式REST_FRAMEWORK={ 'DEFAULT_PARSER_CLASSES': ( 'rest_framework.parsers.JSONParser', 'rest_framework.parsers.FormParser', ),}
-3、如果都没有配置的话那就使用默认的配置:
'DEFAULT_PARSER_CLASSES': ( 'rest_framework.parsers.JSONParser', 'rest_framework.parsers.FormParser', 'rest_framework.parsers.MultiPartParser' )
看到这可能就懵逼了,不过没关系,这几种方法其实都是因为分析了源码之后得出的,下面就一起来分析一下源码的执行流程吧:
Content-Type: application/url-encoding..... //数据格式
request.body # 请求体中的原生数据 request.POST request.data #reqest.data是APIView重装request才有的,reqest.data取值的时候才执行解析器组件Content-Type: application/json..... //数据格式
request.body # 请求体中的原生数据 request.POST request.data #reqest.data是APIView重装request才有的,reqest.data取值的时候才执行解析器组件from django.db import modelsclass Author(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) age = models.IntegerField() def __str__(self): return self.nameclass Publish(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) city = models.CharField(max_length=32) email = models.EmailField() def __str__(self): return self.nameclass Book(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField(max_length=32) publishDate = models.DateField() price = models.DecimalField(max_digits=5, decimal_places=2) # 与Publish建立一对多的关系,外键字段建立在多的一方 publish = models.ForeignKey(to="Publish", to_field="nid", on_delete=models.CASCADE) # 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表 authors = models.ManyToManyField(to='Author', )
缺点:需要自己设计数据格式、需要自己做序列化操作、需要自己讲不支持json序列化的数据类型转化
class Booklist(View): def get(self, request): book_obj = models.Book.objects.all() ret = [] for obj in book_obj: ret.append({ "title":obj.title, "price":"%s"%obj.price, }) return HttpResponse(json.dumps(ret,ensure_ascii=False))
缺点:只支持序列化,而不支持校验、错误提示等附加功能
from django.core.serializers import serialize class Booklist(View): def get(self, request): book_obj = models.Book.objects.all() data = serialize("json", book_obj) return HttpResponse(data)
DRF ( Django RestFramework ) Serializer的序列化方式可以类比Django的Form组件的使用
注意一点:因为Serializer和数据库没有实质上的联系,所以post请求时不能直接保存到数据库from rest_framework.views import APIViewfrom app001 import models# rest_framework重装的responsefrom rest_framework.response import Response# 序列化组件的导入from rest_framework import serializersclass BooklistSerializer(serializers.Serializer): title = serializers.CharField(max_length=32) price = serializers.DecimalField(max_digits=5, decimal_places=2) publishDate = serializers.DateTimeField() # 一对多字段,可以通过source参数取出想要的关联对象的任意字段 publish_name = serializers.CharField(source="publish.name",read_only=True) publish_city = serializers.CharField(source="publish.city",read_only=True) # 多对多字段,可以通过source参数取出所有关联对象queryset集合,几乎没用 # authors = serializers.CharField(max_length=32, source="authors.all",read_only=True) # 多对多字段,固定的书写格式 authors = serializers.SerializerMethodField(read_only=True) def get_authors(self, obj): # 函数命名必须是get_field形式,obj为当前字段对象 ret = [] for obj in obj.authors.all(): ret.append(obj.name) return retclass Booklist(APIView): # 查 get def get(self, request): book_obj = models.Book.objects.all() bs = BooklistSerializer(book_obj, many=True) data = bs.data # 序列化接口 return Response(data) #增 post def post(self, request): print(request.data) # 静态方法:解析数据工作 bs = BooklistSerializer(data=request.data) if bs.is_valid(): # 校验 return Response(bs.data) # 序列化数据 else: return Response(bs.errors) # 序列化错误信息
DRF ( Django RestFramework ) Serializer的序列化方式可以类比Django的ModelForm组件的使用
当涉及到一对多或者多对多字段时,我们可以通过自定制操作来获得我们想要的数据形式, 更多更细相关序列化内容请看:class BooklistSerializer(serializers.ModelSerializer): //serializers.ChoiceField字段也可以通过source="get_字段名_display"的方式取出对应数字的中文简介 //一对多字段,可以通过source参数取出想要的关联对象的任意字段 //一对多字段,需要添加read_only=True参数,这个参数在post请求时有用 publish_name = serializers.CharField(source="publish.name",read_only=True) publish_city = serializers.CharField(source="publish.city",read_only=True) // 多对多字段,固定的书写格式 // 函数命名必须是get_field形式,obj为当前字段对象 authors = serializers.SerializerMethodField() def get_authors(self, obj): ret = [] for obj in obj.authors.all(): ret.append(obj.name) return ret class Meta: model=models.Book fields="__all__" //指定所有字段 extra_kwargs={"publish":{"write_only":True},"authors":{"write_only":True}} //设置post写入的只写不读字段class Booklist(APIView): def get(self, request): book_obj = models.Book.objects.all() bs = BooklistSerializer(book_obj, many=True) data = bs.data # 序列化接口 return Response(data) def post(self, request): // 静态方法:解析数据工作 print(request.data) //post请求时不仅仅是序列化了,还需要验证、保存等,必须在实例化时加上data //post发送的是添加请求,单个对象many=False bs = BooklistSerializer(data=request.data,many=False) // 校验 if bs.is_valid(): bs.save() // create操作 return Response(bs.data) // 序列化数据 else: return Response(bs.errors) // 序列化错误信息
转载地址:http://ybrfa.baihongyu.com/