基于APIView写接口

基于APIView写五个接口

一、视图层代码

"""
基于APIView实现接口的编写
用的是同一个模型表
路由也没变
这次做了解耦合
写了序列化类 与视图类分开了
"""

from rest_framework.views import APIView
from .models import Book
from .serializer import BookSeSerializer
from rest_framework.response import Response


class BookView(APIView):
    def get(self, request):  # 查所有数据
        # 先查出来数据
        books = Book.objects.all()
        # instance是要序列化的数据 是queryset对象 ,因此要传many=True
        ser = BookSeSerializer(instance=books, many=True)
        return Response(ser.data)

    def post(self, request):  # 新增一个
        # 获取前端传入的数据
        ser = BookSeSerializer(data=request.data)
        # 先校验数据
        if ser.is_valid():
            # 校验通过就保存
            ser.save()
            # 给前端返回保存结果
            return Response({'code': 100, 'msg': '新增数据成功', 'result': ser.data})
        else:
            return Response({'code': 101, 'msg': ser.errors})


class BookDetailView(APIView):
    def get(self, request, *args, **kwargs):  # 查询单个
        # 查询单个数据
        book = Book.objects.filter(pk=kwargs.get('pk')).first()
        # 序列化,因为点first()了所以不是queryset对象,因此不用传many=True
        ser = BookSeSerializer(instance=book)
        # 返回给前端看
        return Response(ser.data)

    def put(self, request, pk):
        # 先查询出来
        book = Book.objects.filter(pk=pk).first()
        # 反序列化数据
        ser = BookSeSerializer(data=request.data, instance=book)
        # 校验反序列化的数据
        if ser.is_valid():
            # 如果数据校验合法就保存到数据库
            ser.save()
            return Response({'code': 100, 'msg': '数据修改成功', 'result': ser.data})
        else:
            return Response({'code': 101, 'msg': ser.errors})

    def delete(self, request, pk):
        Book.objects.filter(pk=pk).delete()
        return Response({'code': 999, 'msg': '删除成功'})

二、序列化类代码

from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from .models import Book

"""
在这里写序列化类
写序序列化某些字段的类属性
里面写保存逻辑和修改逻辑<<<<这个是反序列化保存的过
写局部钩子和全局钩子来校验前端传过来的数据
"""


class BookSeSerializer(serializers.Serializer):
    # 序列化某些字段 serializers下大致跟models下的类是对应的
    name = serializers.CharField()
    price = serializers.CharField()
    publish = serializers.CharField()

    def create(self, validated_data):
        # 保存逻辑,validated_data是校验过后的数据,保存到数据库
        book = Book.objects.create(**validated_data)
        return book

    def update(self, instance, validated_data):
        instance.name = validated_data.get('name')
        instance.price = validated_data.get('price')
        instance.publish = validated_data.get('publish')
        instance.save()
        return instance

    def validate_name(self, name):
        # 局部钩子 校验name是否合法
        if name.startswith('sb'):
            print('why???')
            raise ValidationError('不能以sb开头')
        else:
            return name

    def validate(self, attrs):
        # 全局钩子 校验过后的数据,设置书名和出版社名字不能一致 当然只是为了节目效果
        if attrs.get('name') == attrs.get('publish'):
            raise ValidationError('书名和出版社名字不能一致')
        else:
            return attrs

三、路由代码

from django.contrib import admin
from django.urls import path
from app01 import views


urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/v1/books/', views.BookView.as_view()),
    path('api/v1/books/<int:pk>/', views.BookDetailView.as_view()),

]

四、模型表代码

from django.db import models


class Book(models.Model):
    name = models.CharField(max_length=32, verbose_name='书名')
    price = models.CharField(max_length=32, verbose_name='价格')
    publish = models.CharField(max_length=32, verbose_name='出版社')

当然是得有数据,模型层,用的依然是基于view写接口的表数据,反正今天的重点是研究接口的编写!

posted @ 2023-02-09 08:35  阿丽米热  阅读(58)  评论(0编辑  收藏  举报
Title