第四节 Django rest framework路由器与限流等

git补充

在这里插入图片描述
在这里插入图片描述

drf补充

在这里插入图片描述

开始之前

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

修改功能

1.写视图

 def update(self, request, pk):
        # 查询要修改的数据
        try:
            student = Student.objects.get(id=pk)
        except Student.DoesNotExist:
            return Response(status=HTTP_404_NOT_FOUND)
        # 获取前端传入的数据进行反序列化
        serializer = StudentSerializer(student, data=request.data)  # 序列化对象没有传入instance, save()做create保存;传入则进行update保存
        # 校验
        serializer.is_valid(raise_exception=True)
        # 对数据进行修改
        serializer.save()
        return Response(serializer.data)  # 通过序列化器对象的data属性获取序列化后的数据(json格式的数据)

在这里插入图片描述

2. 写路由

在这里插入图片描述

3.效果

在这里插入图片描述

4. 做修改

在这里插入图片描述
在这里插入图片描述

删除功能

1.写视图

 def destroy(self, request, pk):
        # 查询要修改的数据
        try:
            student = Student.objects.get(id=pk)
        except Student.DoesNotExist:
            return Response(status=HTTP_404_NOT_FOUND)

        student.delete()
        return Response(status=HTTP_204_NO_CONTENT)


在这里插入图片描述

2. 写路由

在这里插入图片描述

3. 页面效果

在这里插入图片描述

4.删除

在这里插入图片描述

总:
1.模型类

from django.db import models

# Create your models here.

class Student(models.Model):
    SEX_CHOICES = (
        (0, '女'),
        (1, '男'),
    )
    name = models.CharField(max_length=30, verbose_name='姓名')
    age = models.IntegerField(verbose_name='年龄', null=True, blank=True)
    sex = models.IntegerField(verbose_name='性别', null=True, blank=True, choices=SEX_CHOICES)
    create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
    update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
    is_delete = models.BooleanField(default=False, verbose_name='逻辑删除')

    class Meta:   #定义原信息
        db_table = 'student'  # 将映射的表名设置为 student
2.序列化器

# -*- coding: utf-8 -*-
# @Time     : 2021/11/12
# @Author   : LY
# @Email    : ly@mq.com
# @File     : .py
# @Software :
"""
    序列化器
        本质就是一个类,和模型类差不多的类
        用于JSON格式与模对象进行互转以及校验数据

        定义的属性就是要参与转换的字段

        序列化器字段可以少于或多于模型类字段(属性)

        定义返回的数据有哪些字段

"""
from rest_framework import serializers
from .models import Student

class StudentSerializer(serializers.ModelSerializer):
   class Meta:
       model = Student  # 指定序列化器映射的模型类
       fields = '__all__'  # fields指定映射字段__all__表示所有字段
       # fields = ['id', 'name', 'age']  # 只映射id,name,age
       # exclude = ['id']  # 映射除id字段之外的所有字段
       # 修改映射字段
       extra_kwargs = {
           'age': {'min_value': 0, 'max_value': 200},
       }

   # 追加额外的校验逻辑
   def validate_name(self, value):
       if 'python' not in value.lower():
           raise serializers.ValidationError('name error')
       return value

   # # 对象级别的额外验证
   #
   # def validate(self, data):
   #     if 'python' not in data['name'].lower():
   #         raise serializers.ValidationError('name error')
   #     return data


3.视图

from django.shortcuts import render
from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework.status import HTTP_404_NOT_FOUND, HTTP_204_NO_CONTENT

from .models import Student
from .serializers import StudentSerializer


# Create your views here.

class StudentViewSet(viewsets.ViewSet):
    def list(self, request):
        # 获取所有的学生信息,返回的是模型类集合
        student = Student.objects.all()
        # 序列化: 实例化序列化器。传入要转换的模型集合,如果是多条数据一般我们加一个参数many=True
        serializer = StudentSerializer(student, many=True)
        # 返回响应: 返回序列化后的数据
        return Response(serializer.data)

    def create(self, request):
        # 获取前端传入的数据
        serializer = StudentSerializer(data=request.data)  # 得到的是前端的数据,我们需要转模型,反序列化
        # 校验
        serializer.is_valid(raise_exception=True)

        # 保存数据
        serializer.save()
        # 返回响应: 返回序列化数据
        return Response(serializer.data)

    def retrieve(self, request, pk):
        try:
            student = Student.objects.get(id=pk)
        except Student.DoesNotExist:
            return Response(status=HTTP_404_NOT_FOUND)

        serializer = StudentSerializer(instance=student)  # instance 序列化 , data 反序列化
        return Response(serializer.data)

    def update(self, request, pk):
        # 查询要修改的数据
        try:
            student = Student.objects.get(id=pk)
        except Student.DoesNotExist:
            return Response(status=HTTP_404_NOT_FOUND)
        # 获取前端传入的数据进行反序列化
        serializer = StudentSerializer(student, data=request.data)  # 序列化对象没有传入instance, save()做create保存;传入则进行update保存
        # 校验
        serializer.is_valid(raise_exception=True)
        # 对数据进行修改
        serializer.save()
        return Response(serializer.data)  # 通过序列化器对象的data属性获取序列化后的数据(json格式的数据)

    def destroy(self, request, pk):
        # 查询要修改的数据
        try:
            student = Student.objects.get(id=pk)
        except Student.DoesNotExist:
            return Response(status=HTTP_404_NOT_FOUND)

        student.delete()
        return Response(status=HTTP_204_NO_CONTENT)



4. 路由

from django.urls import path
from .views import StudentViewSet

urlpatterns = [
    path('student/', StudentViewSet.as_view({'get': 'list', 'post': 'create'})),
    path('student/<pk>/', StudentViewSet.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'}))
]

	假设你要进行老师对学生表的管理,然后需要写老师的增删改查,与学生模型一
样,只是数据不一样,会使得我们进行重复复杂的操作。于是drf帮我们做了升级,帮
我们定义了ModelViewSet,帮我们实现了所有的方法(增删改查),我们只需要定义
数据集和序列化器就可以了。只有数据不一样(学生变老师),然后序列化器不一样
(不同的数据用不同的序列化器进行转化),我们只需要定义不一样的地方,交给
drf进行带入处理。

1. 修改视图

class StudentViewSet(viewsets.ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer

在这里插入图片描述

2. 网页效果

在这里插入图片描述

3. 查询

在这里插入图片描述

4.修改

在这里插入图片描述
在这里插入图片描述

5.增加

在这里插入图片描述
在这里插入图片描述

6.删除

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

关于 ModelViewSet
按住ctr键+鼠标点击 ModelViewSet,进入class ModelViewSet,里面已经帮忙定义了五种方法,如果只想要显示其中某一种,就直接继承对应的类,比如只想要查询功能(这里这作为介绍)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

路由升级

1.创建路由

from rest_framework.routers import SimpleRouter
from .views import StudentViewSet

urlpatterns = [

]

router = SimpleRouter()  # 创建路由器
router.register('student', StudentViewSet)   # 注册路由
urlpatterns += router.urls  # 获取生成的路由列表,然后拼接

在这里插入图片描述

逻辑删除

1.起因

在这里插入图片描述

2. 修改模型类
    def delete(self, using=None, keep_parents=False):
        self.is_delete = True
        self.save()

在这里插入图片描述

3. 删除效果

在这里插入图片描述
在这里插入图片描述

4.优化查询功能
class StudentViewSet(ModelViewSet):
    # queryset = Student.objects.all()
    queryset = Student.objects.filter(is_delete=False)
    serializer_class = StudentSerializer

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

关联序列化

1. 被 表Student 添加外键字段,关联 class 班级表,现在需要删表重建,所以要注释与该表有关的所有信息

在这里插入图片描述

2.迁移映射

在这里插入图片描述

3.将注释掉的所有信息 crt+z 撤回,恢复原样。之前的操作是为了删除数据库里面的表。
4. 定义好模型
from django.db import models


# Create your models here.

class Student(models.Model):
    SEX_CHOICES = (
        (0, '女'),
        (1, '男'),
    )
    name = models.CharField(max_length=30, verbose_name='姓名')
    age = models.IntegerField(verbose_name='年龄', null=True, blank=True)
    sex = models.IntegerField(verbose_name='性别', null=True, blank=True, choices=SEX_CHOICES)
    create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
    update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
    is_delete = models.BooleanField(default=False, verbose_name='逻辑删除')

    classes = models.ForeignKey('Classse', on_delete=models.CASCADE)  # 外键
    class Meta:  # 定义原信息
        db_table = 'student'  # 将映射的表名设置为 student

    def delete(self, using=None, keep_parents=False):
        self.is_delete = True
        self.save()

class Classse(models.Model):
    name = models.CharField(max_length=30, verbose_name="班级名")
    slogan = models.TextField(verbose_name="口号", null=True, blank=True)
    create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
    update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
    is_delete = models.BooleanField(default=False, verbose_name='逻辑删除')

    class Mete:   # 定义原信息,更改表名
        db_table = 'Classse'

    def delete(self, using=None, keep_parents=False):  # 逻辑删除
        self.is_delete = True
        self.save()

在这里插入图片描述

5.迁移映射

在这里插入图片描述

6.写序列化器
# -*- coding: utf-8 -*-
# @Time     : 2021/11/12
# @Author   : LY
# @Email    : ly@mq.com
# @File     : .py
# @Software :
"""
    序列化器
        本质就是一个类,和模型类差不多的类
        用于JSON格式与模对象进行互转以及校验数据

        定义的属性就是要参与转换的字段

        序列化器字段可以少于或多于模型类字段(属性)

        定义返回的数据有哪些字段

"""
from rest_framework import serializers
from .models import Student, Classse

class StudentSerializer(serializers.ModelSerializer):
   class Meta:
       model = Student  # 指定序列化器映射的模型类
       fields = '__all__'  # fields指定映射字段__all__表示所有字段
       # fields = ['id', 'name', 'age']  # 只映射id,name,age
       # exclude = ['id']  # 映射除id字段之外的所有字段
       # 修改映射字段
       extra_kwargs = {
           'age': {'min_value': 0, 'max_value': 200},
       }

   # 追加额外的校验逻辑
   def validate_name(self, value):
       if 'python' not in value.lower():
           raise serializers.ValidationError('name error')
       return value

   # # 对象级别的额外验证
   #
   # def validate(self, data):
   #     if 'python' not in data['name'].lower():
   #         raise serializers.ValidationError('name error')
   #     return data


class ClassseSerializer(serializers.ModelSerializer):
    class Meta:
        model = Classse  # 指定序列化器映射的模型类
        fields = '__all__'  # fields指定映射字段__all__表示所有字段

    def validated_name(self, value):
        if '码趣教育' not in value:
            raise serializers.ValidationError('班级名需要带有码趣教育')
        return value


在这里插入图片描述

7.写视图

from rest_framework.viewsets import ModelViewSet

from .models import Student, Classse
from .serializers import StudentSerializer, ClassseSerializer


# Create your views here.

class StudentViewSet(ModelViewSet):
    # queryset = Student.objects.all()
    queryset = Student.objects.filter(is_delete=False)
    serializer_class = StudentSerializer   # 指定序列化器


class ClassViewSet(ModelViewSet):
    # queryset = Student.objects.all()
    queryset = Classse.objects.filter(is_delete=False)
    serializer_class = ClassseSerializer


在这里插入图片描述

8.写路由
from rest_framework.routers import SimpleRouter
from .views import StudentViewSet, ClassViewSet

urlpatterns = [

]

router = SimpleRouter()  # 创建路由器
router.register('student', StudentViewSet)   # 注册路由
router.register('class', ClassViewSet)   # 注册路由
urlpatterns += router.urls  # 获取生成的路由列表,然后拼接

在这里插入图片描述

9.效果

在这里插入图片描述

10.添加数据

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

11.修改

在这里插入图片描述
在这里插入图片描述

12.新增班级

在这里插入图片描述
在这里插入图片描述

13.返回班级里所有的学生(班级关联学生)
student_set = StudentSerializer(many=True)

在这里插入图片描述
在这里插入图片描述

说明部分:因为个人原因,这里已经删除表格重建,就是上面有步骤说明,相关表格信息全部注释然后映射提交。
我只是为了修改表名,话不多说,强迫症犯病了。取消所有注释,修改表名后,在映射提交。
1)模型类

from django.db import models


# Create your models here.

class Student(models.Model):
    SEX_CHOICES = (
        (0, '女'),
        (1, '男'),
    )
    name = models.CharField(max_length=30, verbose_name='姓名')
    age = models.IntegerField(verbose_name='年龄', null=True, blank=True)
    sex = models.IntegerField(verbose_name='性别', null=True, blank=True, choices=SEX_CHOICES)
    create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
    update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
    is_delete = models.BooleanField(default=False, verbose_name='逻辑删除')

    classes = models.ForeignKey('Classes', on_delete=models.CASCADE)  # 外键
    class Meta:  # 定义原信息
        db_table = 'student'  # 将映射的表名设置为 student

    def delete(self, using=None, keep_parents=False):
        self.is_delete = True
        self.save()

class Classes(models.Model):
    name = models.CharField(max_length=30, verbose_name="班级名")
    slogan = models.TextField(verbose_name="口号", null=True, blank=True)
    create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
    update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
    is_delete = models.BooleanField(default=False, verbose_name='逻辑删除')

    class Mete:   # 定义原信息,更改表名
        db_table = 'class'

    def delete(self, using=None, keep_parents=False):  # 逻辑删除
        self.is_delete = True
        self.save()

    def __str__(self):
        return self.name

2)序列化器

# -*- coding: utf-8 -*-
# @Time     : 2021/11/12
# @Author   : LY
# @Email    : ly@mq.com
# @File     : .py
# @Software :
"""
    序列化器
        本质就是一个类,和模型类差不多的类
        用于JSON格式与模对象进行互转以及校验数据

        定义的属性就是要参与转换的字段

        序列化器字段可以少于或多于模型类字段(属性)

        定义返回的数据有哪些字段

"""
from rest_framework import serializers
from rest_framework.relations import StringRelatedField

from .models import Student, Classes


class StudentSerializer(serializers.ModelSerializer):
    # Classes = StringRelatedField(read_only=True)
    class Meta:
        model = Student  # 指定序列化器映射的模型类
        fields = '__all__'  # fields指定映射字段__all__表示所有字段
        # fields = ['id', 'name', 'age']  # 只映射id,name,age
        # exclude = ['id']  # 映射除id字段之外的所有字段
        # 修改映射字段
        extra_kwargs = {
            'age': {'min_value': 0, 'max_value': 200},
        }

    # 追加额外的校验逻辑
    def validate_name(self, value):
        if 'python' not in value.lower():
            raise serializers.ValidationError('name error')
        return value

    # # 对象级别的额外验证
    #
    # def validate(self, data):
    #     if 'python' not in data['name'].lower():
    #         raise serializers.ValidationError('name error')
    #     return data


class ClassesSerializer(serializers.ModelSerializer):
    # student_set = StudentSerializer(many=True)

    class Meta:
        model = Classes  # 指定序列化器映射的模型类
        fields = '__all__'  # fields指定映射字段__all__表示所有字段

    def validated_name(self, value):
        if '码趣教育' not in value:
            raise serializers.ValidationError('班级名需要带有码趣教育')
        return value

3)视图


from rest_framework.viewsets import ModelViewSet

from .models import Student, Classes
from .serializers import StudentSerializer, ClassesSerializer


# Create your views here.

class StudentViewSet(ModelViewSet):
    # queryset = Student.objects.all()
    queryset = Student.objects.filter(is_delete=False)
    serializer_class = StudentSerializer   # 指定序列化器


class ClassViewSet(ModelViewSet):
    # queryset = Student.objects.all()
    queryset = Classes.objects.filter(is_delete=False)
    serializer_class = ClassesSerializer



4)路由

# -*- coding: utf-8 -*-
# @Time     : 2021/11/12
# @Author   : LY
# @Email    : ly@mq.com
# @File     : .py
# @Software :

from rest_framework.routers import SimpleRouter
from .views import StudentViewSet, ClassViewSet

urlpatterns = [

]

router = SimpleRouter()  # 创建路由器
router.register('student', StudentViewSet)   # 注册路由
router.register('class', ClassViewSet)   # 注册路由
urlpatterns += router.urls  # 获取生成的路由列表,然后拼接

5)总路由

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('user/', include('user.urls'))

]

1.班级获取学生信息

在这里插入图片描述

在这里插入图片描述

2.逻辑删除

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

发现一个问题:我的表名为啥没有更改成功?原因是Meta写成了Mete了,于是我修改后,重新映射提交后,表明被成功修改

在这里插入图片描述
在这里插入图片描述

3. 获取最后一条数据
 @action(methods=['get'], detail=False)  # 定义路由的请求方法 detail=False 不需要通过编号去获取
    def last(self, request):
        classes = Classes.objects.last()    # 查询最后一条数据,及最新的数据
        serializer = self.get_serializer(classes)  # 拿到指定的序列化器
        return Response(serializer.data)

在这里插入图片描述
在这里插入图片描述

修改
  @action(methods=['get'], detail=False)  # 定义路由的请求方法 detail=False 不需要通过编号去获取
    def last(self, request):
        # classes = Classes.objects.last()    # 查询最后一条数据,及最新的数据
        classes = Classes.objects.filter(is_delete=False).last()    # 去掉逻辑删除查询最后一条数据,及最新的数据
        serializer = self.get_serializer(classes)  # 拿到指定的序列化器
        return Response(serializer.data)

在这里插入图片描述
在这里插入图片描述

新增一个功能,添加路由只需要@装饰器(设置访问的请求方式,设是否是详情的方法)
反爬的功能(有时候会被限流,限制访问的次数,为了保护服务器)
1.新建一个配置
REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': [
        'rest_framework.throttling.AnonRateThrottle',  # 没有登录(匿名)的访问频次
        'rest_framework.throttling.UserRateThrottle'  # 登录的用户访问频次
    ],
    'DEFAULT_THROTTLE_RATES': {
        'anon': '100/day',  # 匿名访问次数(1天)  # day hour minute second 都可以设置
        'user': '1000/day'  # 用户访问次数(1天)
    }
}

在这里插入图片描述

2.修改设置访问

在这里插入图片描述
在这里插入图片描述

如何生成官方文档?
1.下载依赖包
 pip install coreapi -i https://pypi.douban.com/simple

在这里插入图片描述

2. 重启pycharm
3. 配置

'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema'

在这里插入图片描述

3. 配置接口文档使用路由(总路由)

from django.contrib import admin
from django.urls import path, include
from rest_framework.documentation import include_docs_urls

urlpatterns = [
    path('admin/', admin.site.urls),
    path('user/', include('user.urls')),
    path('docs/', include_docs_urls('DRF Study API 接口文档')),

]

在这里插入图片描述

5. 访问路由(看接口文档)

在这里插入图片描述

6.修改描述说明

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

7.添加中文说明

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

补充内容:删除分支

《(2)项目的介绍与配置(用户注册实现)》这篇文章有写到,就不再重复了

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YY2065

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值