django前后分离-restful

Posted deaseyy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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文件中的MyJsonRenderer类方法

2.重构JSONRenderer下的render方法

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

class MyJsonRenderer(JSONRenderer):
    def render(self, data, accepted_media_type=None, renderer_context=None):
       # 重构方法一:
       # try:
        #     code = data.pop(‘code‘)
        #     msg = data.pop(‘msg‘)
        # except:
        #     code = 200
        #     msg = ‘请求成功‘
        # try:
        #     result = data.pop(‘data‘)
        # except:
        #     result = data
            
        # 重构方法二:  ps: 实现原理都一样
        code = data.pop(code, 200)
        msg = data.pop(msg, 请求成功)
        result = data.pop(data, data)
        
        # 将http响应状态码改为200, 若不加,抛错时,http的响应状态码会显示500,前端ajax请求信息会是失败,不会进入then,直接执行catch里的语句
        renderer_context[response].status_code = 200
        
        res = {
            code: code,
            msg: msg,
            data: result,
        }
        return super().render(res,accepted_media_type=None, renderer_context=None)

 

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):
    ...

 


?

 

以上是关于django前后分离-restful的主要内容,如果未能解决你的问题,请参考以下文章

django前后分离-restful

Python前后端分离开发Vue+Django REST framework实战

Python前后端分离开发Vue+Django REST framework实战

django中cbv源码和restful规范

Python前后端分离开发Vue+Django REST framework实战

Vue+Django REST framework前后端分离平台开发之项目初始化