返回顶部
首页 > 资讯 > 后端开发 > Python >django-rest-framewor
  • 220
分享到

django-rest-framewor

djangorestframewor 2023-01-30 23:01:24 220人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

源码繁琐,多说无益,耐心细读官方文档: https://www.Django-rest-framework.org/   个人总结:   REST是一种软件架构设计风格,不是标准,也不是具体的技术实现,只是提供了一组设计原则和约束条件。

源码繁琐,多说无益,耐心细读官方文档:

https://www.Django-rest-framework.org/

 

个人总结:

 

REST是一种软件架构设计风格,不是标准,也不是具体的技术实现,只是提供了一组设计原则和约束条件。

DRF(DjanGo RestFramework)是一套基于Django开发的、帮助我们更好的设计符合REST规范的WEB应用的一个Django App,所以,本质上,它是一个Django App。

安装: (确定Django已经安装)

   >>> pip install djangorestframework

 

 

1 apiView 

  首先需要了解django中views.View类及其相关流程,看如下关系图(最好看源码):

 

  DRF APIView请求流程:

 

 

 

  DRF对django视图配置流程图(个人画)

 

 

2 解析器组件 (用来解析数据的请求的组件)

  Django并不能处理请求协议为application/JSON编码协议的数据

  注意: DRF解析器会封装到View中的parsers内,在视图函数被调用时,会传入request,通过request.data拿到数据才进行解析 ,即解析器解析是在request对象传入后.

  解析器组件流程图:

 

 

//解析器的使用方式:

    //1,导入模块 views.py
        from rest_framwork.views import APIView
    
    //2, 继承APIView
        class BookView(APIView):
            def get(self, request):
                pass

    //3, url.py
        from django.urls import path, include, re_path
        from classbasedview import views
        urlpatterns = [
            re_path('login/$', views.LoginView.as_view()),
        ]


    //4, def post(self, request):
            origin_data = request.data
                ...
                return HttpResponse({})
                   

 

  试用工具: postman---通过postman来模拟用户请求,不再需要使用浏览器来发送请求.(直接在官网下载即可)


3 序列化组件 

  序列化组件的使用:

  --get接口设计:

  • 导入序列化组件:from rest_framework import serializers
  • 定义序列化类,继承serializers.Serializer(建议单独创建一个专用的模块用来存放所有的序列化类):class BookSerializer(serializers.Serializer):pass
  • 定义需要返回的字段(字段类型可以与model中的类型不一致,参数也可以调整),字段名称必须与model中的一致
  • 在GET接口逻辑中,获取QuerySet
  • 开始序列化:将QuerySet作业第一个参数传给序列化类,many默认为False,如果返回的数据是一个列表嵌套字典的多个对象集合,需要改为many=True
  • 返回:将序列化对象的data属性返回即可

 

  {{ 实践代码 }}

  --post接口设计

  • url定义:需要为post新增url,因为根据规范,url定位资源,http请求方式定义用户行为
  • 定义post方法:在视图类中定义post方法
  • 开始序列化:通过我们上面定义的序列化类,创建一个序列化对象,传入参数data=request.data(application/json)数据
  • 校验数据:通过实例对象的is_valid()方法,对请求数据的合法性进行校验
  • 保存数据:调用save()方法,将数据插入数据库
  • 插入数据到多对多关系表:如果有多对多字段,手动插入数据到多对多关系表
  • 返回:将插入的对象返回

  {{ 实践代码 }}

  使数据自动插入而且更加简单:

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book

        fields = ('title',
                  'price',
                  'publish',
                  'authors',
                  'author_list',
                  'publish_name',
                  'publish_city'
                  )
        extra_kwargs = {
            'publish': {'write_only': True},
            'authors': {'write_only': True}
        }

    publish_name = serializers.CharField(max_length=32, read_only=True, source='publish.name')
    publish_city = serializers.CharField(max_length=32, read_only=True, source='publish.city')

    author_list = serializers.SerializerMethodField()

    def get_author_list(self, book_obj):
        # 拿到queryset开始循环 [{}, {}, {}, {}]
        authors = list()

        for author in book_obj.authors.all():
            authors.append(author.name)

        return authors

  步骤如下:

    继承ModelSerializer: 不再继承Serializer

    添加extra_kwargs类变量: extra_kwargs = { 'publish':{'write_only':True}}

 

4 视图组件

  使用视图组件进行接口逻辑化

   导入mixin

from rest_framework.mixinx import (
                    ListModelMix,
                    CreateModelMixin,
                    DestroyModelMixin,
                    UpdateModelMixin,
                    RetrieveModelMixin       
                                  )
from rest_framework.generics import GenericAPIView
             

    定义序列化类

Class BookSerializer(serializers.ModelSerializer):
  class Meta:
    Book
      fields = ()
      extra_kwargs = {"field_name": {"write_only": True}}

 

    导入序列化类

    from .app_serializers import BookSerializer

  定义视图类

            class BookView(ListModelMix, CreateModelMixin, GenericAPIView):
                # queryset和serializer_class是固定的写法
                queryset = Book.objects.all()
                serializer_class = BookSerializer
              
                def get():
                    return self.list()
                
                def post():
                    return self.create()
                    
            class BookFilterView(RetrieveModelMixin, DestroyModelMixin, UpdateModelMixin, GenericAPIView):
                queryset = Book.objects.all()
                serializer_class = BookSerializer
                
                def get():
                    return self.retrieve()
                    
                def delete():
                    return self.destroy()
                    
                def put():
                    return self.update()

 

   注意: 单条数据操作的url是这样的:re_path(r'books/(?P<pk>\d+)/$, views.BookFilterView.as_view())

 

  使用视图组件的view进行接口逻辑优化

    导入模块  from rest_framework import generics

    写试图类

class BookView(generics.ListCreateAPIView)
                    queryset = Book.objects.all()
                    serializer_class = BookSerializer
                    
                class BookFilterView(generics.RetrieveUpdateDestroyAPIView):
                    queryset = Book.objects.all()
                    serializer_class = BookSerializer

 

  使用视图组件的viewset进行接口逻辑优化

    导入模块 from rest_framework.viewset import ModelViewSet

    设计url

re_path(r'books/$, views.BookView.as_view({
                    'get': 'list',
                    'post': 'create'
                })),
                re_path(r'books/(?P<pk>\d+)/$', views.BookView.as_view({
                    'get': 'retrieve',
                    'delete': 'destroy',
                    'put': 'update'
                }))

 

 

 

    设计视图类

       class BookView(ModelViewSet):
           queryset = Book.objects.all()
           serializer_class = BookSerializer

 

 

  • Django程序启动,开始初始化,获取配置信息,获取视图类并加载到内存中,获取url及视图类的对应关系
  • 开始绑定视图类和url的对应关系,执行as_view()方法
  • as_view()方法被执行的时候传递了参数,为字典形式:{ “get”: “retrieve”, “delete”: “destroy”, “put”: “update” }
  • 上一步中执行as_view()方法传递参数的目的是为了完成优化,将delete请求方式重新命名为不同的函数
  • ViewSetMixin类重写了as_view()方法,也就是在这个地方将几个函数重新绑定,它并没有重写dispatch方法
  • 该方法返回视图函数view,注意在这个函数中有一个行 self = cls(**initkwargs), cls是视图类,执行视图函数时self就指向视图函数的实例对象
  • 等待客户端请求
  • 请求到来,开始执行视图函数,注意,调用视图函数时的方式是view(request),而如果url带有参数,调用方式为view(request, xxx=id)的形式
  • 显然,我们有命名参数(?P\d+),所以此时的调用方式为view(request, pk=id)
  • 视图函数中有一行self.kwargs = kwargs,所以pk已经被视图函数找到了
  • 视图函数返回self.dispatch(),开始执行dispatch方法,注意self是视图类的实例化对象(每个请求都被封装为一个对象)
  • dispatch开始执行get方法,注意此时的get方法会执行retrieve,以为已经被重定向了
  • 开始执行retrieve,有一行instance = self.get_object(), 该方法在GenericAPIView中
  • 至关重要的是拿到self.kwargs中的pk关键字,然后从queryset中拿到想要的数据
  • 返回结果

 

 

5 认证组件

  cookie和session两种方式可以保存用户信息,这两种方式不同的是cookie保存在客户端浏览器中,而session保存在服务器中,他们各有优缺点,配合起来使用,可将重要的敏感的信息存储在session中,而在cookie中可以存储不太敏感的数据。

  token称之为令牌。cookie、session和token都有其应用场景,没有谁好谁坏,不过开发数据接口类的Web应用,目前用token还是比较多的。

  token认证步骤:

    用户登录,服务器端获取密码,查询用户表,如果存在该用户且第一次登录(或者token过期), 生成token,否则返回错误信息

    如果用户不是第一次登录,且token未过期,更新token值

  创建俩个model,(token可以存储在user表中,建议存储在user表中):

    

from django.db import models

# Create your models here.

class User(models.Model):
    username = models.CharField(max_length=32)
    passWord = models.CharField(max_length=32)
    user_type_entry = (
        (1, 'Delux'),
        (2, 'SVIP'),
        (3, "VVIP")
    )
    user_type = models.IntegerField(choices=user_type_entry)
    address = models.CharField(max_length=32)

    def __str__(self):
        return self.username

class UserToken(models.Model):
    user = models.OneToOneField("User", on_delete=models.CASCADE)
    token = models.CharField(max_length=128)

  因为涉及登录认证,所以写post方法接口,登录都是post请求:

  

from django.http import JsonResponse

from rest_framework.views import APIView

from .models import User, Book, UserToken
from .utils import get_token


class UserView(APIView):

    def post(self, request):
        response = dict()
        try:
            username = request.data['username']
            password = request.data['password']

            user_instance = User.objects.filter(
                user_name=username,
                password=password
            ).first()

            if user_instance:
                access_token = get_token.generater_token()

                UserToken.objects.update_or_create(user=user_instance, defaults={
                    "token": access_token
                })
                response["status_code"] = 200
                response["status_message"] = "登录成功"
                response["access_token"] = access_token
                response["user_role"] = user_instance.get_user_type_display()
            else:
                response["status_code"] = 201
                response["status_message"] = "登录失败,用户名或密码错误"
        except Exception as e:
            response["status_code"] = 202
            response["status_message"] = str(e)

        return JsonResponse(response)

  通过获取随机字符串的方法用来生成token值:

# -*- coding: utf-8 -*-
import uuid


def generater_token():
    random_str = ''.join(str(uuid.uuid4()).split('-'))
    return random_str

  DRF认证组件的使用:

    新建一个认证类,包含之后的认证逻辑:

class UserAuth(object):

    def authenticate_header(self, request):
        pass

    def authenticate(self, request):
        user_post_token = request.query_params.get('token')

        token_object = UserToken.objects.filter(token=user_post_token).first()
        if token_object:
            return token_object.user.username, token_object.token
        else:
            raise APIException("认证失败")

  实现方式看上去非常简单,到token表里面查看token是否存在,然后根据这个信息,返回对应信息即可,然后,在需要认证通过才能访问的数据接口里面注册认证类即可: 

class BookView(ModelViewSet):

    authentication_classes = [UserAuth, UserAuth2]

    queryset = Book.objects.all()
    serializer_class =  BookSerializer

  多个认证类实现:

    注意:若需要返回数据,请在最后一个认证类中返回,因为在前面返回,self.authentication()方法中会对返回值进行判断,若不为空,认证的过程就会终止.  多个认证类实现方式如下:

class UserAuth2(object):

    def authenticate(self, request):
        raise APIException("认证失败")


class UserAuth(object):

    def authenticate_header(self, request):
        pass

    def authenticate(self, request):
        user_post_token = request.query_params.get('token')

        token_object = UserToken.objects.filter(token=user_post_token).first()
        if token_object:
            return token_object.user.username, token_object.token
        else:
            raise APIException("认证失败")


class BookView(ModelViewSet):

    authentication_classes = [UserAuth, UserAuth2]

  简化authenticate_header方法,如下:(继承BaseAuthentication类即可)

from rest_framework.authentication import BaseAuthentication

class UserAuth2(BaseAuthentication):

    def authenticate(self, request):
        raise APIException("认证失败")


class UserAuth(BaseAuthentication):

    def authenticate(self, request):
        user_post_token = request.query_params.get('token')

        token_object = UserToken.objects.filter(token=user_post_token).first()
        if token_object:
            return token_object.user.user_name, token_object.token
        else:
            raise APIException("认证失败")

 

  全局认证: 

    实现所有的数据接口都需要认证:  

authentication_classes=api_settings.DEFAULT_AUTHENTICATION_CLASSES

  如果认证类自己没有authentication_classes,就会到settings中去找,通过这个机制,我们可以将认证类写入到settings文件中即可实现全局认证:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'authenticator.utils.authentication.UserAuth',
        'authenticator.utils.authentication.UserAuth2',
    ),
}

 

6 权限组件 

  定义权限类: 

class UserPerms():
    message = "您没有权限访问该数据"
    def has_permission(self, request, view):
        if request.user.user_type > 2:
            return True
        else:
            return False

  同样的逻辑,同样的方式,只是执行权限的方法名与执行认证的方法名不一样而已,名为has_permission,并且需要将当前的视图类传递给该方法。

  视图类中加入permission_classes变量:

class BookView(ModelViewSet):

    authentication_classes = [UserAuth]
    permission_classes = [UserPerms2]

    queryset = Book.objects.all()
    serializer_class =  BookSerializer

 

7 频率组件


8 url控制器组件
9 分页器组件
10 响应器组件

 

--结束END--

本文标题: django-rest-framewor

本文链接: https://lsjlt.com/news/180436.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Django Rest Framewor
    REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移” REST从资源的角度类审视整个网络,它将分布在网络中某个节点的资源通过URL进行...
    99+
    2023-01-30
    Django Rest Framewor
  • django-rest-framewor
    源码繁琐,多说无益,耐心细读官方文档: https://www.django-rest-framework.org/   个人总结:   REST是一种软件架构设计风格,不是标准,也不是具体的技术实现,只是提供了一组设计原则和约束条件。 ...
    99+
    2023-01-30
    django rest framewor
  • Django-REST-Framewo
    We're going to create a simple API to allow admin users to view and edit the users and groups in the system. Project se...
    99+
    2023-01-31
    Django REST Framewo
  • django rest framework http status code
    判断请求是否成功,可以从返回的状态码来区别,所以当写接口的时候也要这样做,标准化.from rest_framework import status通过导入status,里面已经定义好了状态码,源码如下:"""...
    99+
    2023-01-31
    framework rest django
  • MVC3+Entity Framewor
     本节内容主要以实际操作为主: 1.创建MVC3.0项目: 2.创建数据库Vote: 因为本程序只是教程例子,所以没有复杂的表结构,只是为了方便大家学习创建。数据库为Vote,其中只有一张表Users,表中字段分别为id(主键自动增涨列...
    99+
    2023-01-31
    Entity Framewor
  • Django REST framework 异常处理
    目录写在前面DRF异常处理1. DRF 常见的异常2. 自定义异常3. 使用自定义异常4. 验证结果异常处理进阶1. 修改自定义异常2. 自定义更多异常3. 新增测试接口4. 验证结...
    99+
    2024-04-02
  • Django REST Framework该怎么理解
    今天就跟大家聊聊有关Django REST Framework该怎么理解,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。1.Django REST framework框架介绍Djang...
    99+
    2023-06-02
  • Django REST framework 限流功能的使用
    目录正文开始 1. DRF 中的限流 2. 限流进阶配置 3. 限流思路分析 4. 源码分析 5. 其它注意事项 参考资料 正文开始 先说一个限流这个概念,最早接触这个概念是在前端...
    99+
    2024-04-02
  • django rest framework之请求与响应(详解)
    前言:在上一篇文章,已经实现了访问指定URL就返回了指定的数据,这也体现了RESTful API的一个理念,每一个URL代表着一个资源。当然我们还知道RESTful API的另一个特性就是,发送不同的请求动...
    99+
    2022-06-04
    详解 django rest
  • 深度解析Django REST Framework 批量操作
    目录DRF基本情况自定义批量操作批量创建批量删除批量更新djangorestframework-bulk依赖安装范例路由测试DRF3相关注意事项源码解读我们都知道Django res...
    99+
    2024-04-02
  • Django rest framework如何自定义用户表
    目录说明1. Django项目和应用创建2. 自定义User表3. 序列化和路由3. DRF配置4. 同步数据库5. 测试6. 命令行注册用户说明 Django 默认的用户表 aut...
    99+
    2024-04-02
  • Django REST Framework 批量操作的示例分析
    这篇文章将为大家详细讲解有关Django REST Framework 批量操作的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。DRF基本情况我们以下面的代码作为例子:models:from&nb...
    99+
    2023-06-15
  • Django rest framework自定义用户表的方法
    这篇文章主要介绍了Django rest framework自定义用户表的方法,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。说明Django 默认的用户表 auth_user...
    99+
    2023-06-15
  • Django Rest Framework实现身份认证源码详解
    目录一.Django框架二.身份认证的两种实现方式:三.身份认证源码解析流程一.Django框架 Django确实是一个很强大,用起来很爽的一个框架,在Rest Framework中...
    99+
    2024-04-02
  • Django REST框架:如何使用HTTP API构建Web服务?
    Django REST框架是一个基于Django的强大的Web API框架,它使得构建Web服务变得更加容易和快速。本文将介绍如何使用Django REST框架来构建HTTP API服务。 安装Django REST框架 首先,需要安...
    99+
    2023-11-12
    django http git
  • Python的Django REST框架中的序列化及请求和返回
    序列化Serialization 1. 设置一个新的环境 在我们开始之前, 我们首先使用virtualenv要创建一个新的虚拟环境,以使我们的配置和我们的其他项目配置彻底分开。 $mkdir ~/env...
    99+
    2022-06-04
    框架 序列化 Python
  • 一步步教你如何在 Django REST API 中构建使用 JWT 验证
    基于令牌的身份验证,允许后端服务与前端(无论是web端,原生移动端或其他端)分离,并驻留在不同域中。 JSON Web Tokens (JWT) 是一种流行的令牌认证实现, 在本文中,我们使用它来验证,通过Django REST 框架.构建...
    99+
    2022-05-31
    Python Django JWT 验证
  • 一步步教你如何在 Django REST API 中构建使用 JWT 验证
    基于令牌的身份验证,允许后端服务与前端(无论是web端,原生移动端或其他端)分离,并驻留在不同域中。 JSON Web Tokens (JWT) 是一种流行的令牌认证实现, 在本文中,我们使用它来验证,通过Django REST 框架.构建...
    99+
    2023-02-09
    Django API python爬虫
  • golang实现rest server
    背景 用golang对数据库标准操作进行封装,为后面的rest server提供数据库访问层。实现的目标是:能根据rest请求参数自动生成数据库操作语句,提供增、删、改、查、批量写入、事务等必要的数据库操作封装。并可以方便的扩展到多种数...
    99+
    2023-01-31
    golang rest server
  • RyuBook1.0案例三:REST L
    该小结主要介绍如何添加一个REST Link 函数 RYU本身提供了一个类似WSGI的web服务器功能。借助这个功能,我们可以创建一个REST API。 基于创建的REST API,可以快速的将RYU系统与其他系统或者是浏览器相连接,非...
    99+
    2023-01-30
    案例 REST
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作