RESTful API

参考文档

  • 到底是什么?
    • URI代表资源
      • 每个URI代表一类资源
    • 客户端和服务器传输的内容叫做表现层 在http 请求头 使用 accept Content-Type
    • 客户端通过不同的请求方式来使表现层发生状态转换

在这里插入图片描述
在这里插入图片描述
数据为 json 格式 身份认证 给予一个秘钥
在这里插入图片描述
难点:对象和字典之间的转换
djangorestframework框架
中文框架的参考文档

安装完毕,需要在 settings 像注册app 一样
在这里插入图片描述

模型
简单的书籍模型

class Book(models.Model):
    b_name = models.CharField(max_length=32, null=False)
    b_price = models.FloatField(default=10)

创建一个序列化类
开发 web API 需要提供为代码片段实例序列化和反序列化 像 json 这种方式
序列化类继承的父类里面有抽象方法,子类继承后必须重写,不然会报错

from rest_framework import serializers
from .models import Book

class BookSerializers(serializers.Serializer):
    id = serializers.IntegerField(read_only=True)
    b_name = serializers.CharField(required=True, max_length=32)
    b_price = serializers.FloatField(default=10)

    def update(self, instance, validated_data):
        # or 第一个为真 短路 不执行第二个
        instance.b_name = validated_data.get('b_name') or instance.b_name
        instance.b_price = validated_data.get('b_price') or instance.b_price

        return instance

    def create(self, validated_data):
        return Book.objects.create(**validated_data)

视图
在这里插入图片描述

class BookSerializersView(View):
    def get(self,request,*args, **kwargs):
        books = Book.objects.all()
        serializer = BookSerializers(books, many=True)
        data = {
            'msg':'OK',
            'status':200,
            'data': serializer.data

        }
        return JsonResponse(data)  #返回的响应为json
    def post(self, request, *args, **kwargs):
        b_name = request.POST.get('b_name')
        b_price = request.POST.get('b_price')
        book_data = {
            'b_name': b_name,
            'b_price': b_price
        }
        serializer = BookSerializers(data=book_data) #返回新创建的书籍
        if not serializer.is_valid():
            data = {
                'msg':'FAIL',
                'status':400,   #用户发出的请求有错误
                'data': serializer.errors

            }
            return JsonResponse(data)
        serializer.save()
        data = {
            'msg':'OK',
            'status':201,
            'data':serializer.data
        }
        return JsonResponse(data)

ModelSerializer
不用再重写类方法

from rest_framework import serializers
from .models import Book

class BookModelSerialzers(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = ['id','b_name','b_price']
class BookModelSerializersView(View):
    def get(self,request,*args, **kwargs):
        books = Book.objects.all()
        serializer =BookModelSerialzers(books, many=True)
        data = {
            'msg':'OK',
            'status':200,
            'data': serializer.data

        }
        return JsonResponse(data)  #返回的响应为json
    def post(self, request, *args, **kwargs):
        b_name = request.POST.get('b_name')
        b_price = request.POST.get('b_price')
        book_data = {
            'b_name': b_name,
            'b_price': b_price
        }
        serializer = BookModelSerialzers(data=book_data) #返回新创建的书籍
        if not serializer.is_valid():
            data = {
                'msg':'FAIL',
                'status':400,   #用户发出的请求有错误
                'data': serializer.errors

            }
            return JsonResponse(data)
        serializer.save()
        data = {
            'msg':'OK',
            'status':201,
            'data':serializer.data
        }
        return JsonResponse(data)

在这里插入图片描述
使用 Response 返回

class MyserializersBook(APIView):
    def get(self,request, format =None):
        books = Book.objects.all()
        serializer = BookModelSerialzers(books, many=True)
        data = {
            'msg':'OK',
            'status':200,
            'data':serializer.data
        }
        return Response(data)

    def post(self,request, format = None):
        b_name = request.POST.get('b_name')
        b_price = request.POST.get('b_price')

        data = {
            'b_name': b_name,
            'b_price':b_price
        }
        serializer = BookModelSerialzers(data=data)
        if not serializer.is_valid():
            data = {
                'msg':'FAIL',
                'status':status.HTTP_400_BAD_REQUEST,
                'data':serializer.errors
            }
            return Response(data)
        serializer.save()
        data = {
            'msg':'OK',
            'status':status.HTTP_201_CREATED,
            'data':serializer.data
        }
        return Response(data)

路由中

urlpatterns = format_suffix_patterns(urlpatterns)

使用类视图的最大优势之一,可以轻松地创建可替代的行为

之前我们创建的任何基于模型的 API 视图在 REST 框架中 是使用 mixin 类实现的
mixins 把增删改查等 做了封装, 比起继承 APIView 还是比较方便的
通过 minxin 类编写视图
参考,很不错
下面两个类要注意 继承的是谁
返回多条数据,或者新建 书籍

class BookMixin(mixins.RetrieveModelMixin,
                mixins.UpdateModelMixin,
                mixins.DestroyModelMixin,
                generics.GenericAPIView,
                mixins.ListModelMixin,
                mixins.CreateModelMixin):
    queryset = Book.objects.all()
    serializer_class = BookModelSerialzers

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)
     def post(self,request, *args, **kwargs): 
        print(request.data)
        return self.create(request,*args,**kwargs)
     

路由

path('mixinone',views.BookMixin.as_view(), name='mixinone'),

单条数据

class BookDetailkMixin(mixins.RetrieveModelMixin,
                mixins.UpdateModelMixin, #更新
                mixins.DestroyModelMixin,  #删除数据
                generics.GenericAPIView,
                mixins.ListModelMixin, #查询所有
                mixins.CreateModelMixin):  #创建
    queryset = Book.objects.all()
    serializer_class = BookModelSerialzers

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)
    def delete(self,request, *args, **kwargs):
        return self.destroy(request,*args, **kwargs)

路由
需要在路由中指定查询哪本具体的书籍

    path('mixintwo/<int:pk>',views.BookDetailkMixin.as_view(), name='mixintwo')

将全部书籍查询和单本书籍查询合并在一个类
注意继承的谁–> ModelViewSet (这个类也是继承了上面的几个类)

class BookThree(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookModelSerialzers

路由有所变化
路由变为两个,带参数和不带参数,不带默认查询全部书籍,或者增加单本书籍,带参数 删改查

path('three', views.BookThree.as_view({'get':'list','post':'create'}), name ='threeone'),
    path('three/<int:pk>', views.BookThree.as_view({'get':'retrieve','put':'update','delete':'destroy'}))

在这里插入图片描述
——————————————————————————————————————————
mixin中的五中类方法
CreateModelMixin 用户保存数据 post
LIstModelMixin 用户取出多条数据 突然感觉 就是对 APIView 类进行了封装,实现的原理是相同的 get
RetrieveModelMixin 用户取出单条数据 路径需要带参数 get
UpdateModelMixin 用户修改更新数据 put
DeleteModelMixin 用户删除数据 delete
————————————————————————————————————————

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐