安装:pip3 install djangorestframework
注意:如果django版本低于2.2,安装最新版,django也会会被更新到最新版
视图中使用:
from django.shortcuts import render # Create your views here. from rest_framework.views import APIView from rest_framework.response import Response from app01 import models from app01.app01serializers import BookSer class Home(APIView): def get(self, request, *args, **kwargs): res = [ {"id": 1, "msg": "使用HTTPS传输数据"}, {"id": 2, "msg": "api名称尽量使用名词复数,例如:Books、GirlFriends;不要使用:GetBook、Getgirl"}, {"id": 3, "msg": "在API地址中要尽量标明这是一个API接口,例如:api.baidu。com、www。baidu。com/api"}, {"id": 4, "msg": "多版本共存,更新api接口时,需要新建一个接口,而不是直接改原来的接口。例如:api.baidu.com/v1、api.baidu.com/v2"}, {"id": 5, "msg": "查询条件在地址中携带,例如:api.baidu.com?title=xyj&limit=10"}, {"id": 6, "msg": "对数据不同的操作方式,通过请求方法来体现,例如:获取GET、添加POST、删除DELETE、修改PUT"}, {"id": 7, "msg": "获取多个数据返回列表,获取单个数据返回字典"}, {"id": 8, "msg": "添加数据需要返回,添加数据的对象;修改数据需要返回被修改对象;删除数据返回空"}, {"id": 9, "msg": "返回的数据中需要携带状态码,例如{code:200,msg:'成功'}"}, {"id": 10, "msg": "在返回的数据中,携带下一次请求的连接,例如:{code:100,msg:成功,result:[{title:西游记,price:10,shop_url:baidu.com}]}"}, ] return Response(res) class Books(APIView): def get(self, request, *args, **kwargs): query_set = models.BookModel.objects.all() # 如果传入的是以一个queryset对象,必须传入many=True ser = BookSer(instance=query_set, many=True) return Response(ser.data) def post(self, request, *args, **kwargs): res = { 'code': 200, 'msg': '成功', 'result': '', 'errors': '' } # 使用APIView以后,rest_frameworkon 将所有数据都封装到了data中 data = request.data ser = BookSer(data=data) if ser.is_valid(): # 校验方式跟form一样,校验通过就调用save保存到数据库,需要注意,保存要自己在BookSer中重写create方法 ser.save() res['result'] = ser.data else: res['code'] = 400 res['msg'] = '失败' res['errors'] = ser.errors return Response(res) class Book(APIView): def get(self, request, id, *args, **kwargs): book = models.BookModel.objects.filter(pk=id).first() ser = BookSer(instance=book) return Response(ser.data) def put(self, request, id, *args, **kwargs): res = { 'code': 200, 'msg': '成功', 'result': '', 'errors': '' } book = models.BookModel.objects.filter(pk=id).first() ser = BookSer(instance=book, data=request.data) if ser.is_valid(): ser.save() res['result'] = ser.data else: res['code'] = 400 res['msg'] = '失败' res['errors'] = ser.errors return Response(res) def delete(self, request, id, *args, **kwargs): res = { 'code': 200, 'msg': '成功', 'result': '', 'error': '' } try: book = models.BookModel.objects.filter(pk=id).delete() except Exception: res['error'] = str(Exception) return Response(res)
序列化使用:
from rest_framework import serializers from rest_framework.exceptions import ValidationError from app01 import models class BookSer(serializers.Serializer): """ read_only=False, 只读字段,用于显示。就算上传了也不会存入数据库 write_only=False, 只写字段,用于保存,不会向前端从传递 required=None, 是否可以为空,True可以 None不可以 default=empty, 默认值,如果前端没有往后端传值,保存时会用默认值 initial=empty, source=None, label=None, 标题 help_text=None,提示信息 style=None, error_messages=None, 错误提示 validators=None, 字段校验,跟局部钩子类似,可以传递一个列表,列表中放多个校验函数,校验函数的写法跟局部钩子一样,函数名随意 allow_null=False 是否可以传空,注意不是是否可以不传 """ title = serializers.CharField(label='书籍名称', max_length=32, min_length=2) price = serializers.FloatField(label='书籍价格', max_value=99999, min_value=1, read_only=True) publish = serializers.CharField(label='出版社名称', max_length=32, min_length=2) def validate_title(self, data): """ 局部钩子,用于校验字段是否合法,跟form的局部钩子类似 :param data: :return: """ if data.lower().startswith('sb'): raise ValidationError('书籍名称不能以SB开头') return data def validate(self, attrs): """ 全局钩子 :param attrs: :return: """ if self.instance: return attrs title = attrs.get('title') publish = attrs.get('publish') book = models.BookModel.objects.filter(title=title, publish=publish) if book: raise ValidationError('已存在相同书籍...') return attrs def create(self, validated_data): # 如果要保存,必须重写create方法 obj = models.BookModel.objects.create(**validated_data) return obj def update(self, instance, validated_data): for k, v in validated_data.items(): if hasattr(instance, k): setattr(instance, k, v) instance.save() return instance