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)

定义的数据库模型,也就是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',)

项目文件结构

请求提交参数脚本

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自定义视图类及实现请求参数和返回参数加解密的更多相关文章

  1. Django 自定义分页类

    分页类代码: class Page(object): ''' 自定义分页类 可以实现Django ORM数据的的分页展示 输出HTML代码: 使用说明: from utils import mypag ...

  2. Django框架视图类

    类视图 在写视图的时候,Django除了使用函数作为视图,也可以使用类作为视图.使用类视图可以使用类的一些特性,比如继承等. View django.views.generic.base.View是主 ...

  3. django自定义管理类的save model和delete model记一次进一步了解

    业务背景: 最近在写一个个人博客网站,文章分类是一个自关联的两层分类.希望在点开分类时,显示一级分类.一级分类下的所有二级分类以及每个二级分类有多少个文章.最简单办法就是关联查询,查询出所有二级分类, ...

  4. [py][mx]django自定义认证类-实现邮箱作为用户名登录

    创建自定义验证用户名密码类CustomBackend users/views.py from django.contrib.auth import authenticate, login from d ...

  5. httpclient工具类,post请求发送json字符串参数,中文乱码处理

    在使用httpclient发送post请求的时候,接收端中文乱码问题解决. 正文: 我们都知道,一般情况下使用post请求是不会出现中文乱码的.可是在使用httpclient发送post请求报文含中文 ...

  6. Spring MVC参数绑定(如何接收请求参数及返回参数)

    在SpringMVC interceptor案例实践中遇到了获取jsp表单传递参数失败的问题,怎么的解决的呢?下面详细介绍. 先讲述下https://www.cnblogs.com/ilovebath ...

  7. Kotlin入门(24)如何自定义视图

    Android提供了丰富多彩的视图与控件,已经能够满足大部分的业务需求,然而计划赶不上变化,总是有意料之外的情况需要特殊处理.比如PagerTabStrip无法在布局文件中指定文本大小和文本颜色,只能 ...

  8. [转载]开发 Spring 自定义视图和视图解析器

    原文出处 http://www.ibm.com/developerworks/cn/java/j-lo-springview/ 概述 Spring 3.0 默认包含了多种视图和视图解析器,比如 JSP ...

  9. Android自定义视图

    Android框架为我们提供了大量的视图类来帮助我们做好展示信息以及同用户进行交互的工作.然后有时候,我们的app或许需要一些在Android内建视图之外特殊的视图,那么此时我们就需要自定义视图.下面 ...

  10. iOS-xib(使用XIB实现嵌套自定义视图)

    参考:http://wtlucky.github.io/geekerprobe/blog/2014/08/10/nested-xib-views/?utm_source=tuicool 因为主要练习x ...

随机推荐

  1. javaEE Web(Tomcat)深度理解 和 Servlet的本质

    javaEE Web(Tomcat)深度理解 和 Servlet的本质 每博一文案 我所有的进步,只为更接近你. 上天没有给予人们公平的人生,有人拥有出奇的才能,便有人只能不辞辛苦的攀登阶梯,我默默地 ...

  2. C#多线程开发-处理异步操作中的异常

    C#多线程开发-处理子线程中的异常 在平时的多线程开发中,对于异常的处理是至关重要的,千万不能马虎.如果在实际的项目中,对于某些线程中的异常没有处理,会直接导致整个程序崩溃,软件无法使用. 其中需要说 ...

  3. 探究平台化设计的核心思想和Lattice的设计原则

    一. 平台对业务敏捷支撑的挑战 早期阿里的交易中台遇到了一些挑战,这个在毗卢的博客中有提到,主要遇到了这些问题:新小业务都有一个成长规律,在早期业务模式验证阶段,需要的玩法比较简单,希望能频繁的发布快 ...

  4. Unity C# IEnumrator 与 async 有的区别

    前言 IEnumerator 和 async 是在 Unity 和 C# 中处理异步编程的两种不同方法.它们各自有不同的使用场景和优缺点. IEnumerator IEnumerator 是 C# 中 ...

  5. 移动端网页--better-scroll介绍

    移动端网页--better-scroll介绍 Options 起始位置及滚动方向 startX:0 开始时的X轴位置 startY:0 开始时的Y轴位置 scrollY: true 滚动方向为 Y 轴 ...

  6. 【小白晋级大师】如何设计一个支持10万人用的ChatGPT对接系统

    不停地书写,方能不失在人海茫茫. 1.前言 之前给大家写了ChatGPT对接企业微信的教程,具体可看知乎链接: [奶奶看了都会]ChatGPT3.5接入企业微信,可连续对话 文章结尾说了教程只能适用于 ...

  7. 在 Linux 内公网、云服务器搭建一套 K8s 集群

    前言 本文讲述如果在 Linux 搭建内/公网 Kubernetes 集群的详细步骤,解决搭建过程中的问题. 准备工作 Linux CentOS 7.x 两台及以上,本文用的 7.6 本文配置默认是在 ...

  8. 五月十一号java基础知识点

    1.通过add()方法向链表list输入1-10十个数for (int i = 1; i <11 ; i++) { list.add(i);//向链表添加1-10的整数 } import jav ...

  9. 性能最快的代码分析工具,Ruff 正在席卷 Python 圈!

    几天前,Python 开源社区又出了一个不小的新闻:HTTPX 和 Starlette 在同一天将在用的代码分析工具(flake8.autoflake 和 isort)统一替换成了 Ruff. HTT ...

  10. SpringBoot2:@Configuration 注解

    @Configuration 这个注解的作用,告诉 springboot 这是一个配置类.配置类以及类里的方法都可以作为Bean.里面的方法用@Bean标记. @Configuration 替换了繁琐 ...