• django前后分离-restful


    前言

    REST是所有Web应用都应该遵守的架构设计指导原则。

    Representational State Transfer,翻译是”表现层状态转化”。

    REST核心: 资源, 状态转移, 统一接口

    资源: 是REST最明显的特征,是指对某类信息实体的抽象,资源是服务器上一个可命名的抽象概念,资源是以名词为核心来组织的,首先关注的是名词。

    状态转移: 是指客户端痛服务端进行交互的过程中,客户端能够通过对资源的表述,实现操作资源的目的

    统一接口: REST要求,必须通过统一的接口来对资源执行各种操作。对于每个资源只能执行一组有限的操作。 比如,客户端通过HTTP的4个请求方式(POST, GET, PUT, PATCH)来操作资源,也就意味着不管你的url是什么,不管请求的资源是什么但操作的资源接口都是统一的。

    GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT(PATCH)用来更新资源,DELETE用来删除资源。

     

    一.django中使用restful

    1.安装相关库

    pip install djangorestframework==3.4.6
    pip install django-filter # 用于过滤

     

    2.settings.py配置的修改

    在工程目录中的settings.py文件的INSTALLED_APPS中需要添加rest_framework

    INSTALLED_APPS = [
    ...

      'rest_framework',
    ]

     

    3.在应用app中定义路由URL

    定义路由需要注意:

    1. 使用router.register注册的url为资源,而且资源只能为名词不能为动词。

    2. 定义的资源不要加'/'斜杠,在访问地址的时候,URL中会默认的添加反斜杠'/'

      from django.conf.urls import url
       
       from rest_framework.routers import SimpleRouter
       
       from app import views
       
       # 引入路由
       router = SimpleRouter()
       # 使用router注册的地址
       router.register(r'^student', views.StudentView)
       
       urlpatterns = [
       
       ]
       urlpatterns += router.urls

    4.在视图views.py文件中定义StudentView类

    具体的详细介绍在地址

    通过定义StudentView并继承了mixins的方法,即可有对应个增删改查的方法。在StudentView中还定义了两个变量queryset、serializer_class。

    from rest_framework import viewsets, mixins
    ​
    from app.models import Student
    from app.serializers import StudentSerializer
    ​
    ​
    class StudentView(mixins.ListModelMixin,
                      mixins.CreateModelMixin,
                      mixins.DestroyModelMixin,
                      mixins.RetrieveModelMixin,
                      mixins.UpdateModelMixin,
                      viewsets.GenericViewSet):
    ​
        # 返回数据
        queryset = Student.objects.all()  # 需要需要序列化的数据
        # 序列化结果
        serializer_class = StudentSerializer  #指定序列化的类(需自己定义)

    其中queryset参数表示需要需要序列化的数据 serializer_class参数指定序列化的类

     

    5.定义序列化类

    序列化类需要继承ModelSerializer,使用ModelSerializer表明序列化整个Student模型,并且可以指定虚拟化哪些字段。

    from rest_framework import serializers
    ​
    from app.models import Student
    ​
    class ArticleSerializer(serializers.ModelSerializer):
        # 序列化时,创建资源需对传入的字段进行校验
        title = serializers.CharField(required=True, max_length=10, min_length=5,
                                      error_messages={
                                        'required': '标题必填',
                                        'max_length':'最大长度10',
                                        'min_length':'最小长度5'})
        desc = serializers.CharField(required=False)
        
        class Meta:
            # 指定序列化的模型
            model = Article
            # 指定序列化哪些字段
            fields = ['title','desc','id','is_show'] # 展示的字段,指定序列化后才能展示
            
       #进一步校验
        def validate(self, attrs):
            # 校验文章标题是否重复
            title = attrs.get('title')
            if title:
                if Article.objects.filter(title=title).exists():
                    raise ParamsException({'code':1002, 'msg':'标题重复'})
            return attrs      
        # 父类默认调用
        # 将字段定义的值,改成我们想要展示的值(例: is_show的值true变成中文 '展示')
        def to_representation(self, instance):
            data = super().to_representation(instance)
            data['is_show'] = '展示' if data['is_show'] else '不展示'
            return data

    通过以上的代码,可以通过以下的URL和HTTP请求方式,完成对资源Student的CRUD操作:

    CRUD对应的增删改查:

    增: POST http://127.0.0.1:8080/stu/addStu/

    删: DELETE http://127.0.0.1:8080/stu/addStu/1/

    改: UPDATE http://127.0.0.1:8080/stu/addStu/1/

    查: GET http://127.0.0.1:8080/stu/addStu/1/

     

    二.rest响应重构

    1.修改响应结构

    1.修改settings.py中的返回数据结构的配置信息
    # rest_framework 使用相关配置
    REST_FRAMEWORK = {
        # 分页配置    分页配置只需在setting中设置就ok
        'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
        'PAGE_SIZE': 3,  # 每页几条数据
        
        #过滤配置     根据条件来查找数据
        'DEFAULT_FILTER_BACKENDS':(
            'django_filters.rest_framework.DjangoFilterBackend',
        ),
        
        这里修改返回数据结构的配置信息
        # render的配置 响应时自动调用render方法,将字典转化为json数据
        'DEFAULT_RENDERER_CLASSES':(
            'utils.renderer.MyJsonRenderer',
        )
    ​
    }

    注意: 定义default_renderer_classes参数,指定render的时候使用我们自定义的renderer.py文件中的CustomJsonRenderer类方法

    2.重构JSONRenderer下的render方法

    该方法继承了JSONRenderer并且重构了render方法,修改了返回的数据结构

    class CustomJsonRenderer(JSONRenderer):
    
        def render(self, data, accepted_media_type=None, renderer_context=None):
    
            if isinstance(data, dict):
                msg = data.pop('msg', '请求成功')
                code = data.pop('code', 0)
            else:
                msg = '请求成功'
                code = 0
         # 将http响应状态码改为200, 若不加,抛错时,http的响应状态码会显示500,
         # 前端ajax请求信息会是失败,不会进入then,直接执行catch里的语句
            response = renderer_context['response']
            response.status_code = 200
    
            res = {
                'code': code,
                'msg': msg,
                'data': data
            }
    
            return super().render(res, accepted_media_type, renderer_context)

    2.异常的响应的结构

    自定义异常处理,一定需要继承from rest_framework.exceptions import APIException 中的APIException,在编写自己的异常处理的方法

     

    三.分页

    修改settings.py配置文件

    只需 在rest_framework配置中,增加分页的配置信息

    REST_FRAMEWORK = {
        # 分页配置    分页配置只需在setting中设置就ok
        'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
        'PAGE_SIZE': 3,  # 每页几条数据
    }

    注意:在结果在data对应的value值中,有一个count的key,表示返回数据有3条,next表示下一个的url,previous表示上一页的url。

    四.过滤

    修改settings.py配置文件,增加filter过滤的信息

    1.安装过滤的库

    pip install django-filter

    2. 配置setings.py的信息

    配置DEFAULT_FILTER_BACKENDS

    django2.0以下版本的配置
    REST_FRAMEWORK = {
        # 分页配置    
        .......
        
        #过滤配置     根据条件来查找数据
        'DEFAULT_FILTER_BACKENDS':(
            'rest_framework.filters.DjangoFilterBackend',
            'rest_framework.filters.SearchFilter',
        ),
    django2.0以上版本的配置
    REST_FRAMEWORK = {
        # 分页配置  
        ........
        #过滤配置     根据条件来查找数据
        'DEFAULT_FILTER_BACKENDS':(
            'django_filters.rest_framework.DjangoFilterBackend',
        ),
    }

    3.views中指定filter_class

    class ArticleView(viewsets.GenericViewSet,  # 提供两个方法
                      mixins.CreateModelMixin,  #创建
                      mixins.ListModelMixin,   #查看所有
                      mixins.DestroyModelMixin, #删除
                      mixins.RetrieveModelMixin, # 查看详情
                      mixins.UpdateModelMixin,  # 修改
                      ):
        # 资源对应所有数据,必须定义该参数,会被源码中get_queryset()方法调用,默认返回它
        queryset = Article.objects.all()
        # 序列化,必须定义该参数, 会被源码中get_serializer()方法调用
        serializer_class = ArticleSerializer
        # 过滤
        filter_class = ArticleFilter  #这里指定过滤调用的类

    4.定义过滤的类

    2.0以上版本
    import django_filters
    ​
    from app.models import Article
    ​
    class ArticleFilter(django_filters.rest_framework.FilterSet):
        # 模糊查询title字段
        title = django_filters.CharFilter(lookup_expr='contains')
        desc = django_filters.CharFilter(lookup_expr='contains')
        # id_min和id_max为接口中定义的过滤参数,其对应到数据库中查询时,对应id字段
        id_min = django_filters.CharFilter('id',lookup_expr='gte')
        id_max = django_filters.CharFilter('id',lookup_expr='lt')
        # 老版本:method改写action
        is_show = django_filters.CharFilter(method='filter_is_show')
        class Meta:
            model = Article
            # 老版本中 fields中定义的参数,才是接口中能过滤的参数
            fields = ['title','desc','id', 'is_show']  # 高版本可不写全
    def filter_is_show(self,queryset, name, value):
            if value == 'on':
                return queryset.filter(is_show=1)
            else:
                return queryset.filter(is_show=0)
    2.0以下版本

    继承的父类修改为: filters.FilterSet

    import django_filters
    from rest_framework import filters
    ​
    class ArticleFilter(filters.FilterSet):
        ...

     

  • 相关阅读:
    mybatis中#{}和${}的区别 (二)
    JAVA分布式架构的演变及解决方案
    mybatis中的#和$的区别
    https
    vue3的组件v-model初探1
    前端性能优化
    HTTP请求的完全过程
    http缓存详解,http缓存推荐方案
    vscode-setting备份
    Mac电脑在finder中添加- 右键打开vscode
  • 原文地址:https://www.cnblogs.com/Deaseyy/p/10903347.html
Copyright © 2020-2023  润新知