django rest_framework

安装: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
原文地址:https://www.cnblogs.com/wtil/p/13927926.html