Django自定义视图类及实现请求参数和返回参数加解密

这篇具有很好参考价值的文章主要介绍了Django自定义视图类及实现请求参数和返回参数加解密。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

django rest_framework中GenericAPIView配合拓展类mixin或者视图集viewset可以复用其代码,减少自己编写的代码量。下面我要实现自己的视图类,以减少代码量


新建一个myView.py
from collections import OrderedDict

from rest_framework import status
from rest_framework.generics import GenericAPIView
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response
from rest_framework.settings import api_settings
from rest_framework.views import APIView


class MyView(APIView):
    queryset = None             # 模型数据
    serializer_class = None     # 序列化类
    filter_class = []           # 过滤字段
    lookup_field = 'id'         # 删改的查找字段
    ordeing_field = ('id',)     # 排序字段
    pagination_class = None     # 分页器

    def get_queryset(self):
        """
        获取queryset数据列表
        """
        assert self.queryset is not None, (
                "'%s' should either include a `queryset` attribute, "
                "or override the `get_queryset()` method."
                % self.__class__.__name__
        )
        self.queryset = self.queryset.all()
        # self.filter_queryset()
        return self.queryset

    def filter_queryset(self, queryset):
        """
        过滤queryset数据
        """
        search_dict = {}
        for fc in self.filter_class:
            field = self.request.query_params.dict().get(fc)
            if field:
                search_dict[fc] = field
        queryset = queryset.filter(**search_dict)
        return queryset

    def get_serializer(self, *args, **kwargs):
        """
        获取序列化模型
        """
        serializer_class = self.get_serializer_class()
        kwargs.setdefault('context', self.get_serializer_context())
        return serializer_class(*args, **kwargs)

    def get_serializer_class(self):
        """
        获取序列化模型类, 判断存在否
        """
        assert self.serializer_class is not None, (
            "'%s' should either include a `serializer_class` attribute, "
            "or override the `get_serializer_class()` method."
            % self.__class__.__name__
        )

        return self.serializer_class

    def get_serializer_context(self):

        return {
            'request': self.request,
            'format': self.format_kwarg,
            'view': self
        }

    def create(self, request, *args, **kwargs):
        """
        创建一条数据
        """
        serializer_class = self.get_serializer_class()
        serializer = serializer_class(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data, status=status.HTTP_201_CREATED)

    def update(self, request, *args, **kwargs):
        """
        更新修改一条数据
        """
        try:
            instance = self.queryset.get(id=request.data.get(self.lookup_field))
        except Exception:
            return Response({'state': 'fail', 'msg': '未找到该数据'}, status=status.HTTP_400_BAD_REQUEST)
        serializer_class = self.get_serializer_class()
        serializer = serializer_class(instance=instance, data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data, status=status.HTTP_201_CREATED)

    def destroy(self, request, *args, **kwargs):
        """
        删除数据,传入的时数组,表示可以删除多条
        """
        try:
            instance = self.queryset.filter(id__in=request.data.get(self.lookup_field))
        except Exception:
            return Response({'state': 'fail', 'msg': '未找到数据'}, status=status.HTTP_400_BAD_REQUEST)
        instance.delete()
        return Response({'state': 'success', 'msg': '删除成功'}, status=status.HTTP_204_NO_CONTENT)

    @property
    def paginator(self):
        """
        分页器属性
        """
        if not hasattr(self, '_paginator'):
            if self.pagination_class is None:
                self._paginator = None
            else:
                self._paginator = self.pagination_class()
        return self._paginator

    def get_paginate_queryset(self, queryset):
        """
        获取分页queryset
        """
        paginator = self.paginator
        if paginator is None:
            return None
        return paginator.paginate_queryset(
            queryset=queryset,
            request=self.request,
            view=self
        )

    def get_paginated_response(self, data):
        """
        获取分页后的返回
        """
        assert self.paginator is not None
        # print(self.paginator.page.paginator.count)
        return self.paginator.get_paginated_response(data)

    def order_by_queryset(self, queryset):
        """
        queryset数据进行排序
        """
        return queryset.order_by(*self.ordeing_field)


class MyPagination(PageNumberPagination):
    page_size = 10    # 表示每页的默认显示数量
    max_page_size = 50  # max_page_size:表示每页最大显示数量,做限制使用,避免突然大量的查询数据,数据库崩溃
    page_size_query_param = 'page_size'   # page_size_query_param:表示url中每页数量参数
    page_query_param = 'page_num'   # page_query_param:表示url中的页码参数

    def get_paginated_response(self, data):
        """
        重构分页返回的数据
        """
        return Response(OrderedDict([
            ('total', self.page.paginator.count),
            ('data', data)
        ]))


class MixinGetPageList:
    """
    get只获取分页数据
    """
    def get(self, request, *args, **kwargs):
        queryset = self.get_queryset()
        queryset = self.filter_queryset(queryset)
        queryset = self.order_by_queryset(queryset)
        serializer_class = self.get_serializer_class()
        queryset = self.get_paginate_queryset(queryset)
        serializer = serializer_class(queryset, many=True)
        return self.get_paginated_response(serializer.data)


class MixinGetAllList:
    """
    get只获取所有数据
    """
    def get(self, request, *args, **kwargs):
        queryset = self.get_queryset()
        queryset = self.filter_queryset(queryset)
        queryset = self.order_by_queryset(queryset)
        serializer_class = self.get_serializer_class()
        serializer = serializer_class(queryset, many=True)
        return Response(serializer.data)


class MixinGetList:
    """
    get获取分页和所有数据
    """
    all_serializer_class = None     # 获取所有的序列化类

    def get(self, request, *args, **kwargs):
        queryset = self.get_queryset()
        queryset = self.filter_queryset(queryset)
        queryset = self.order_by_queryset(queryset)
        params = request.query_params.dict()
        if self.pagination_class is not None and params.get('all') is None:
            serializer_class = self.get_serializer_class()
            queryset = self.get_paginate_queryset(queryset)
            serializer = serializer_class(queryset, many=True)
            return self.get_paginated_response(serializer.data)
        self.serializer_class = self.all_serializer_class
        serializer_class = self.get_serializer_class()
        serializer = serializer_class(queryset, many=True)
        return Response(serializer.data)


class MixinPostCreateModel:
    """
    post增加数据
    """
    def post(self, request):
        return self.create(request)


class MixinPutUpdateModel:
    """
    put修改数据
    """
    def put(self, request):
        return self.update(request)


class MixinDeleteDestroyModel:
    """
    delete删除数据
    """
    def delete(self, request):
        return self.destroy(request)


class MyMixin(MyView):
    """
    增删改查
    """
    def get(self, request, *args, **kwargs):

        queryset = self.get_queryset()
        queryset = self.filter_queryset(queryset)
        queryset = self.order_by_queryset(queryset)

        serializer_class = self.get_serializer_class()
        if self.pagination_class is not None:
            queryset = self.get_paginate_queryset(queryset)
            # print(queryset)

            serializer = serializer_class(queryset, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = serializer_class(queryset, many=True)
        return Response(serializer.data)

    def post(self, request):
        return self.create(request)

    def put(self, request):
        return self.update(request)

    def delete(self, request):
        return self.destroy(request)

 文章来源地址https://www.toymoban.com/news/detail-458364.html

定义的数据库模型,也就是models.py的模型

class Gender(models.Model):
    class Meta:
        db_table = 'gender'
    name = models.CharField(verbose_name="名字", max_length=16)

 

序列化文件 serializer.py 

class GenderSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Gender
        fields = '__all__'

    def create(self, validated_data):
        res = models.Gender.objects.create(**validated_data)
        return res

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

 

然后新建一个视图文件

from ani import models
from ani.serializer import GenderSerializer
from utils.myView import MyPagination, MyView, MixinGetList, MixinPostCreateModel, MixinPutUpdateModel, \
    MixinDeleteDestroyModel


class GenderView(MyView, MixinGetList, MixinPostCreateModel, MixinPutUpdateModel, MixinDeleteDestroyModel):
    queryset = models.Gender.objects.all()
    serializer_class = GenderSerializer
    all_serializer_class = GenderSerializer
    filter_class = ['name__icontains']
    pagination_class = MyPagination
    lookup_field = 'id'
    ordeing_field = ('-id',)

依次继承get、post、put、delete,实现查、增、改、删。

 

 

 

接下来对请求参数,及返回参数进行加密,加解密可以看我之前的文章

先新建一个MyResponse.py,自定义自己的返回类

import json

from rest_framework.response import Response

from utils.encryption import setDataAes


class AESResponse(Response):
    def __init__(self, data=None, secret='www', status=None, template_name=None, headers=None,
                 exception=False, content_type=None):

        enaes_data = setDataAes(secret, json.dumps(data))

        super(AESResponse, self).__init__(data=enaes_data, status=status, template_name=template_name, headers=headers,
                                          exception=exception, content_type=content_type)

 

将myView.py中的Response都替换为自定义返回类,新建了一个myViewEncryp.py

from collections import OrderedDict

from rest_framework import status
from rest_framework.generics import GenericAPIView
from rest_framework.pagination import PageNumberPagination

from rest_framework.settings import api_settings
from rest_framework.views import APIView

from utils.MyResponse import AESResponse
from utils.tools import get_secret


class MyView(APIView):
    queryset = None             # 模型数据
    serializer_class = None     # 序列化模型
    filter_class = []           # 过滤字段
    lookup_field = 'id'         # 删改的查找字段
    ordeing_field = ('id',)     # 排序字段
    pagination_class = None     # 分页器

    def get_queryset(self):
        """
        获取queryset数据列表
        """
        assert self.queryset is not None, (
                "'%s' should either include a `queryset` attribute, "
                "or override the `get_queryset()` method."
                % self.__class__.__name__
        )
        self.queryset = self.queryset.all()
        # self.filter_queryset()
        return self.queryset

    def filter_queryset(self, queryset):
        """
        过滤queryset数据
        """
        search_dict = {}
        for fc in self.filter_class:
            field = self.request.query_params.dict().get(fc)
            if field:
                search_dict[fc] = field
        queryset = queryset.filter(**search_dict)
        return queryset

    def get_serializer(self, *args, **kwargs):
        """
        获取序列化模型
        """
        serializer_class = self.get_serializer_class()
        kwargs.setdefault('context', self.get_serializer_context())
        return serializer_class(*args, **kwargs)

    def get_serializer_class(self):
        """
        获取序列化模型类, 判断存在否
        """
        assert self.serializer_class is not None, (
            "'%s' should either include a `serializer_class` attribute, "
            "or override the `get_serializer_class()` method."
            % self.__class__.__name__
        )

        return self.serializer_class

    def get_serializer_context(self):

        return {
            'request': self.request,
            'format': self.format_kwarg,
            'view': self
        }

    def create(self, request, *args, **kwargs):
        """
        创建一条数据
        """
        serializer_class = self.get_serializer_class()
        serializer = serializer_class(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        secret = get_secret(request)
        return AESResponse(serializer.data, secret=secret, status=status.HTTP_201_CREATED)

    def update(self, request, *args, **kwargs):
        """
        更新修改一条数据
        """
        secret = get_secret(request)
        try:
            instance = self.queryset.get(id=request.data.get(self.lookup_field))
        except Exception:
            return AESResponse({'state': 'fail', 'msg': '未找到该数据'}, secret=secret, status=status.HTTP_400_BAD_REQUEST)
        serializer_class = self.get_serializer_class()
        serializer = serializer_class(instance=instance, data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return AESResponse(serializer.data, secret=secret, status=status.HTTP_201_CREATED)

    def destroy(self, request, *args, **kwargs):
        """
        删除数据,传入的时数组,表示可以删除多条
        """
        secret = get_secret(request)
        try:
            instance = self.queryset.filter(id__in=request.data.get(self.lookup_field))
        except Exception:
            return AESResponse({'state': 'fail', 'msg': '未找到数据'}, secret=secret, status=status.HTTP_400_BAD_REQUEST)
        instance.delete()
        return AESResponse({'state': 'success', 'msg': '删除成功'}, secret=secret, status=status.HTTP_204_NO_CONTENT)

    @property
    def paginator(self):
        """
        分页器属性
        """
        if not hasattr(self, '_paginator'):
            if self.pagination_class is None:
                self._paginator = None
            else:
                self._paginator = self.pagination_class()
        return self._paginator

    def get_paginate_queryset(self, queryset):
        """
        获取分页queryset
        """
        paginator = self.paginator
        if paginator is None:
            return None
        return paginator.paginate_queryset(
            queryset=queryset,
            request=self.request,
            view=self
        )

    def get_paginated_response(self, data):
        """
        获取分页后的返回
        """
        assert self.paginator is not None
        # print(self.paginator.page.paginator.count)
        return self.paginator.get_paginated_response(data)

    def order_by_queryset(self, queryset):
        """
        queryset数据进行排序
        """
        return queryset.order_by(*self.ordeing_field)


class MyPagination(PageNumberPagination):
    page_size = 10    # 表示每页的默认显示数量
    max_page_size = 50  # max_page_size:表示每页最大显示数量,做限制使用,避免突然大量的查询数据,数据库崩溃
    page_size_query_param = 'page_size'   # page_size_query_param:表示url中每页数量参数
    page_query_param = 'page_num'   # page_query_param:表示url中的页码参数

    def get_paginated_response(self, data):
        """
        重构分页返回的数据
        """
        secret = get_secret(self.request)
        return AESResponse(OrderedDict([
            ('total', self.page.paginator.count),
            ('data', data)
        ]), secret=secret)


class MixinGetPageList:
    """
    get只获取分页数据
    """
    def get(self, request, *args, **kwargs):
        queryset = self.get_queryset()
        queryset = self.filter_queryset(queryset)
        queryset = self.order_by_queryset(queryset)
        serializer_class = self.get_serializer_class()
        queryset = self.get_paginate_queryset(queryset)
        serializer = serializer_class(queryset, many=True)
        return self.get_paginated_response(serializer.data)


class MixinGetAllList:
    """
    get只获取所有数据
    """
    def get(self, request, *args, **kwargs):
        queryset = self.get_queryset()
        queryset = self.filter_queryset(queryset)
        queryset = self.order_by_queryset(queryset)
        serializer_class = self.get_serializer_class()
        serializer = serializer_class(queryset, many=True)

        secret = get_secret(request)

        return AESResponse(serializer.data, secret=secret)


class MixinGetList:
    """
    get获取分页和所有数据
    """
    all_serializer_class = None

    def get(self, request, *args, **kwargs):
        queryset = self.get_queryset()
        queryset = self.filter_queryset(queryset)
        queryset = self.order_by_queryset(queryset)
        params = request.query_params.dict()
        if self.pagination_class is not None and params.get('all') is None:
            serializer_class = self.get_serializer_class()
            queryset = self.get_paginate_queryset(queryset)
            serializer = serializer_class(queryset, many=True)
            return self.get_paginated_response(serializer.data)
        self.serializer_class = self.all_serializer_class
        serializer_class = self.get_serializer_class()
        serializer = serializer_class(queryset, many=True)

        secret = get_secret(request)
        return AESResponse(serializer.data, secret=secret)


class MixinPostCreateModel:
    """
    post增加数据
    """
    def post(self, request):
        return self.create(request)


class MixinPutUpdateModel:
    """
    put修改数据
    """
    def put(self, request):
        return self.update(request)


class MixinDeleteDestroyModel:
    """
    delete删除数据
    """
    def delete(self, request):
        return self.destroy(request)


class MyMixin(MyView):
    def get(self, request, *args, **kwargs):

        queryset = self.get_queryset()
        queryset = self.filter_queryset(queryset)
        queryset = self.order_by_queryset(queryset)

        serializer_class = self.get_serializer_class()
        if self.pagination_class is not None:
            queryset = self.get_paginate_queryset(queryset)
            # print(queryset)

            serializer = serializer_class(queryset, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = serializer_class(queryset, many=True)

        secret = get_secret(request)

        return AESResponse(serializer.data, secret=secret)

    def post(self, request):
        return self.create(request)

    def put(self, request):
        return self.update(request)

    def delete(self, request):
        return self.destroy(request)

 

其中加密的密钥是用户的token,或者写死的字符串,tools.py

def get_secret(request):
    """
    获取加密的key
    """
    return request.META.get('HTTP_AUTHORIZATION') or 'wchime'

 

如果前端的请求参数加密,那么需要对参数解密,使用装饰器,decorators.py

def request_decrypt(func):
    """
    解密请求参数
    只对data解密,data传入的必须是字典,不然没有update属性
    """
    def wrap(request, *args, **kwargs):
        data = request.data
        # print(data)
        secret = get_secret(request)
        decrypt_data = getDataAes(secret, data.get('text'))
        if decrypt_data:
            data = json.loads(decrypt_data)
            del request.data['text']
        request.data.update(data)
        # print(decrypt_data)
        return func(request, *args, **kwargs)
    return wrap

 

这时候视图文件需要装饰器解密

from django.utils.decorators import method_decorator

from ani import models
from ani.serializer import GenderSerializer
from utils.decorators import request_decrypt
from utils.myViewEncryp import MyPagination, MyView, MixinGetList, MixinPostCreateModel, MixinPutUpdateModel, \
    MixinDeleteDestroyModel


@method_decorator(request_decrypt, name='put')
@method_decorator(request_decrypt, name='delete')
@method_decorator(request_decrypt, name='post')
class GenderView(MyView, MixinGetList, MixinPostCreateModel, MixinPutUpdateModel, MixinDeleteDestroyModel):
    queryset = models.Gender.objects.all()
    serializer_class = GenderSerializer
    all_serializer_class = GenderSerializer
    filter_class = ['name__icontains']
    pagination_class = MyPagination
    lookup_field = 'id'
    ordeing_field = ('-id',)

 

项目文件结构

Django自定义视图类及实现请求参数和返回参数加解密

 

 

请求提交参数脚本

import json
import requests

from encryption import setDataAes, getDataAes


d = {'name': 'aaa'}
body = setDataAes("wchime", json.dumps(d))
url = 'http://127.0.0.1:4000/ani/gender'
print(body)
data = {'text': body}
res = requests.post(url, json=data)
print(res.text)
print(getDataAes("wchime", res.text))

 

打印结果

Django自定义视图类及实现请求参数和返回参数加解密

 

 

 






到了这里,关于Django自定义视图类及实现请求参数和返回参数加解密的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Django视图-HttpRequest请求对象和HttpResponse响应对象

    服务器在接收到Http请求后,会根据报文创建HttpRequest对象 视图中的第一个参数就是HttpRequest对象 Django框架接收到http请求之后会将http请求包装为HttpRequest对象,之后传递给视图。 新建一个项目 Day05DjangoPro,创建一个应用 叫App 不写子路由啦,直接写根路由 Day05DjangoProurls.py A

    2024年02月12日
    浏览(33)
  • Springboot接口返回参数以及入参RSA加密解密

    网上有好多通过aop切面以及自定义的RSA工具类进行加密解密的方法,期中的过程繁琐也不好用,博主研究了一天从网上到了超好用的基于Springboot框架实现的接口RSA加密解密方式,通过 rsa-encrypt-body-spring-boot 实现了对Spring Boot接口返回值、参数值通过注解的方式自动加解密。

    2024年02月13日
    浏览(34)
  • 前端请求参数加密、.NET 后端解密

    本文详细介绍了前端请求参数加密、.NET 后端解密,文章较长,请各位看官耐心看完。 目录 一、前端使用“CryptoJS”,前端AES加密,.NET后端AES解密 1.1、加密解密效果图 1.2、CryptoJS介绍 1.3、准备工作:安装“CryptoJS” 1.3.1、使用npm进行安装 1.3.2、Visual Studio中安装 1.3.2.1、选择

    2024年02月08日
    浏览(59)
  • 【Spring MVC学习】连接 && 接收请求参数 && 响应返回参数

    目录 前言:认识Spring MVC 🌷1、什么是MVC? 一、建立连接(5个注解) 🌷1、@RequestMapping注解:注册接⼝的路由映射(默认返回页面) 🌷2、@ResponseBody注解:表示返回的是数据 🌷 3、组合注解@RestController = @ResponseBody + @Controller 🌷4、支持Get请求的2种写法@GetMapping + @RequestMapp

    2024年02月16日
    浏览(32)
  • curl请求常用参数和返回码

    curl是一个用于传输数据的工具,支持各种协议,如HTTP、FTP、SMTP等。以下是一些常用的curl请求参数及其作用: -X, --request:指定HTTP请求方法,常见的有GET、POST、PUT、DELETE等。 -H, --header:设置HTTP请求头,用于传递额外的请求信息,例如Authorization、Content-Type等。 -d, --data:设置

    2024年02月05日
    浏览(22)
  • springcloud gateway中打印请求参数,请求路径和返回数据

    在平时前后端联调过程中,需要查询日志看到前端请求的接口,上送的参数,返回数据这样有利于我们定位问题;话不多说直接上代码。 在gateway模块中,新建一个filter的包,然后创建改类,即可在控制台和日志文件里面打印出请求参数,只写了常用的 post 和 get 请求的方式;

    2024年02月15日
    浏览(28)
  • Spring-Cloud-Gateway修改请求(json,form带文件请求)参数,返回值参数

    新项目需要在getway统一做入参、出参加解密,记录日志。记录一下form,x-www-form-urlencoded , json 这几种修改数据的方式。 gateway做拦截器是实现GlobalFilter接口,修改json方式网上有很多文章,后来又想研究研究能不能实现修改form-data参数,以及文件请求,后者文章不多大部分是怎

    2024年02月16日
    浏览(36)
  • 如何为Postman请求自动添加请求返回值作为另一请求传入参数

            在请求的时候会遇到需要带TOKEN的请求,就需要先请求一次获取TOKEN的请求再将返回的值粘贴到下次要请求的地方,这样很麻烦,而POSTMAN提供了方法自动填入传输参数。这里需要两个接口,1号接口是获取TOKEN的,2号接口是需要使用TOKEN的。 这里设置了一个connecti

    2024年02月13日
    浏览(30)
  • python-自定义函数(定义调用、默认参数、返回值)

    本篇文章讲解了python中自定义函数的一些知识点,包括了函数的定义和调用,默认参数,函数返回,其中也添加了比较高级的用法,能适应任何场合 函数是什么:函数是一段可执行的代码块,用于执行特定的任务或完成特定的操作。它由函数名、参数(可选)和函数体组成。

    2024年02月09日
    浏览(36)
  • postman参数化-将上一个接口的返回作为下一个接口的请求参数

    在使用postman做接口测试的时候,在多个接口的测试中,如果需要上一个接口的返回值作为下一个接口的入参,其基本思路是: 1、获取上一个接口的返回值 2、将返回值设置成环境变量或者全局变量 3、设置下一个接口的参数形式 以 下边接口为例: 一、在Tests里设置环境变

    2024年02月11日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包