Django (八) 中间件验证码富文本缓存

 中间件&验证码&富文本&缓存

1. 中间件&AOP

中间件:是一个轻量级的,底层的插件,可以介入Django的请求和响应过程(面向切面编程)
中间件的本质就是一个python
面向切面编程(Aspect Oriented Programming)简称AOPAOP的主要实现目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合的隔离效果。
中间件可实现功能
   - 统计
   - 黑名单
   - 白名单
   - 反爬
   - 界面友好化(捕获异常)

1.1 中间件的可切入点

 

1.2 切入函数

__init__:
    没有参数,服务器响应第一个请求的时候自动调用,用户确定是否启用该中间件
process_request(self,request):
    在执行视图前被调用,每个请求上都会调用,不主动进行返回或返回HttpResponse对象
process_view(self,request,view_func,view_args,view_kwargs)
    调用视图之前执行,每个请求都会调用,不主动进行返回或返回HttpResponse对象
process_template_response(self,request,response):
    在视图刚好执行完后进行调用,每个请求都会调用,不主动进行返回或返回HttpResponse对象
process_response(self,request,response):
    所有响应返回浏览器之前调用,每个请求都会调用,不主动进行返回或返回HttpResponse对象
process_exception(self,request,exception):
    当视图抛出异常时调用,不主动进行返回或返回HttpResponse对象

1.3 自定义中间件

自定义中间件流程
    1.在工程目录下创建middleware目录
    2.目录中创建一个python文件
    3.python文件中导入中间件的基类
        from django.utils.deprecation import MiddlewareMixin
    4.在类中根据功能需求,创建切入需求类,重写切入点方法
        class LearnAOP(MiddlewareMixin):
            def process_request(self,request):
                print('request的路径',request.GET.path)
    5.启用中间件,在settings中进行配置,MIDDLEWARE中添加middleware.文件名.类名
   

 

2.验证码

在用户登录,注册以及一些敏感操作的时候,我们为了防止服务器被暴力请求,或爬虫爬取,我们可以使用验证码进行过滤,减轻服务器的压力。
验证码需要使用绘图 Pillow
    pip install Pillow
核心
    Image,ImageDraw,ImageFont
绘制流程
        backgroundcolor = (10,20,30)   RGB颜色
    初始化画布 
        image = Image.new('RGB',(100,50),backgroundcolor)
    获取画布中画笔对象
        draw = ImageDraw.Draw(image)
    绘制验证码,随机四个
        font = ImageFont.truetype('path',size)
        fontcolor = (20,40,60)
        draw.text((x,y),'R',font,fontcolor)
    最后扫尾
        del draw 
 
        import io
        buf = io.BytesIO()
        Image.save(buf, 'png')
        return HttpResponse(buf.getvalue(),'image/png')

 

3.富文本

富文本:Rich Text FormatRTF),是由微软开发的跨平台文档格式,大多数的文字处理软件都能读取和保存RTF文档,其实就是可以添加样式的文档,和HTML有很多相似的地方
tinymce 插件
django的插件
    pip install django-tinymce
用处大约有两种
    1. 在后台管理中使用
    2. 在页面中使用,通常用来作博客
1.后台中使用:
    配置settings.py文件
        INSTALLED_APPS 添加  tinymce 应用
        添加默认配置
            TINYMCE_DEFAULT_CONFIG = {
                'theme':'advanced',
                'width':600,
                'height':400,
            }
    创建模型类
        from tinymce.models import HTMLField
        class Blog(models.Model):
            sBlog = HTMLField()
    配置站点
        admin.site.register
        
2.在视图中使用:
    使用文本域盛放内容
    <form>
        <textarea></textarea>
    </form>
 
    head中添加script
    <script src='/static/tiny_mce/tiny_mce.js'></script>
    <script>
        tinyMCE.init({
            'mode':'textareas', 'theme':'advanced',
            'width':800,'height':600,
        })
    </script>
    

4. Cache

https://docs.djangoproject.com/zh-hans/2.0/topics/cache/

缓存框架的核心目标

  • 较少的代码

    • 缓存应该尽可能快

    • 因此围绕缓存后端的所有框架代码应该保持在绝对最小值,特别是对于获取操作

  • 一致性

    • 缓存API应该是提供跨越不同缓存后端的一致接口

  • 可扩展性

    • 基于开发人员的需求,缓存API应该可以在应用程序级别扩展

缓存

  • django内置了缓存框架,并提供了几种常用的缓存

    • 基于Memcached缓存

    • 使用数据库进行缓存

    • 使用文件系统进行缓存

    • 使用本地内存进行缓存

    • 提供缓存扩展接口

缓存配置

  1. 创建缓存表

    python manage.py createcachetable [table_name]
  2. 缓存配置

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
            'LOCATION': 'my_cache_table',
            'TIMEOUT': '60',
            'OPTIONS': {
                'MAX_ENTRIES': '300',
            },
            'KEY_PREFIX': 'jack',
            'VERSION': '1',
        }
    }

缓存使用

  • 在视图中使用(使用最多的场景)

  • @cache_page()

    • time 秒 60*5 缓存五分钟

    • cache 缓存配置, 默认default,

    • key_prefix 前置字符串

缓存底层

获取cache

from django.core.cache import cache
cache = cache['cache_name'] cache = cache.get('cache_name')

设置cache

from django.core.cache import cache
cache.set(key, value, timeout)

使用原生缓存来实现

def get_user_list(request):
    # 每次从缓存中获取
    user_cache = cache.get('user_cache')
    # 如果有缓存,则从缓存中直接取
    if user_cache:
        result = user_cache
    # 如果没有缓存,则从数据库中获取
    else:
        # 模拟长时间的数据操作
        user_list = User.objects.all()
        time.sleep(5)
 
        data = {
            'users': user_list,
        }
 
        # 使用模板渲染,得到result文本
        template = loader.get_template('App/stu_list.html')
        result = template.render(data)
                
        # 设置缓存
        cache.set('user_cache', result, 10)
    return HttpResponse(result)

 

转载于:https://www.cnblogs.com/gugubeng/p/9723446.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/464848.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

定位到元素后获取其属性_Selenium界面自动化测试(4)(Python):元素定位及操作...

在操作Web元素之前&#xff0c;需要先找到该元素&#xff0c;这个查找的过程称之为元素定位。Selenium支持8种元素定位方法&#xff1a;ID&#xff1a;根据元素的id属性值来定位元素。Name&#xff1a;根据元素的name属性值来定位元素。Class Name&#xff1a;根据元素的class属…

数据库定时导出和互备一例

环境&#xff1a;内网中有三台服务器做测试用&#xff0c;两台SUSE LINUX 10 和一台RHEL 5.5&#xff0c;都安装有ORACLE11G 需求&#xff1a;测试环境搭建完毕&#xff0c;因没有外部存储进行统一备份而修改和更新又比较频繁&#xff0c;所以需要在三台服务器间搭建互备以实现…

芯片公司急聘嵌入式软件精英人才

薪酬待遇及联系方式薪酬待遇&#xff1a;40~150万不等&#xff0c;另有股票期权等&#xff0c;待遇丰厚&#xff0c;详细面议工作地点&#xff1a;北京市朝阳区联系人&#xff1a;杨先生微信&#xff1a;MichaelYao7PS&#xff1a;推荐成功入职者有推荐费嵌入式软件工程师岗位职…

Python进程学习笔记-multiprocessing模块

如果你打算编写多进程的服务程序&#xff0c;Unix/Linux无疑是正确的选择。由于Windows没有fork调用&#xff0c;难道在Windows上无法用Python编写多进程的程序&#xff1f; 由于Python是跨平台的&#xff0c;自然也应该提供一个跨平台的多进程支持。multiprocessing模块就是跨…

这一年就要过去

「远方钟声响起&#xff0c;这一年就要过去&#xff0c;快乐时光不停留......」楠哥从幼儿园新学习了一首新年小曲。今年已经是12月份了&#xff0c;2021年就要结束&#xff0c;即将到来的是2022年的新的一年。2021年这一年里非常感谢读者的一路支持&#xff0c;当然这不是一篇…

Android 更改签名

本文来自&#xff1a;安卓航班网 签名和发布应用程序 要想使Android应用程序在真机上运行&#xff0c;需要对apk&#xff08;Android应用程序的执行文件&#xff0c;相当于Symbian程序的sis/sisx或Java ME程序的jar文件&#xff09;文件进行签名。可以通过命令行或ADT…

unc 隐藏共享文件夹_你真的了解任务栏吗?win10任务栏居然隐藏了这么多小窍门...

平常使用电脑&#xff0c;最常用的是桌面&#xff0c;桌面上最常用的大约是任务栏&#xff0c;但是你真的了解任务栏吗&#xff1f;除了一小部分朋友熟悉之外&#xff0c;大部分人估计都是没有留意到&#xff0c;其实任务栏就功能角度来说&#xff0c;的确算一个宝藏之地。什么…

c#调api串口通讯

c#调api串口通讯 原文:c#调api串口通讯在调试ICU通信设备的时候&#xff0c;由于串口通信老出现故障&#xff0c;所以就怀疑CF实现的SerialPort类是否有问题&#xff0c;所以最后决定用纯API函数实现串口读写。先从网上搜索相关代码&#xff08;关键字&#xff1a;C# API 串口&…

手机充电IC设置电流与实测电流不一致问题剖析

大家好&#xff0c;我是写代码的篮球球痴&#xff0c;转一篇我朋友记得诚的文章本文转载来自一位基带大佬&#xff0c;解决问题的思路很重要。原文链接&#xff1a;https://blog.csdn.net/AirCity123/article/details/104428325?spm1001.2014.3001.5502某手机的充电架构如下&a…

今天面试了家公司

2011-07-08 不知不觉&#xff0c;做管理软件已经四五年了&#xff0c;今天面试了家做多媒体的公司&#xff0c;感觉不错&#xff0c;想转去做多媒体。转载于:https://blog.51cto.com/3298226/606809

checkbox居中 editor_radio 或 CheckBox 关联 其他元素 整体选择

场景&#xff1a; list组件中&#xff0c;每一行 需要显示多个radio 或者 checkBox&#xff0c;并且每一行显示选择的类型都不一样&#xff01;radio 或checkBox 的选择数据源是存放另一个data组件中&#xff01;&#xff01; 思路&#xff1a;正常的想法是每一行放一个radioGr…

Spring系列(六) Spring Web MVC 应用构建分析

DispatcherServlet DispatcherServlet 是Spring MVC的前端控制器名称, 用户的请求到达这里进行集中处理, 在Spring MVC中, 它的作用是为不同请求匹配对应的处理器, 将结果传递给视图解析器最终呈现给客户端. 前端控制器模式&#xff08;Front Controller Pattern&#xff09;是…

做个好人,加个晚班

我和建平在腾讯加班的日子前几天&#xff0c;他让我给他发照片&#xff0c;因为公司里年末要发照片墙&#xff0c;他说要把我的和他的照片放上去&#xff0c;然后我硬是找了几张觉得不错的给他&#xff0c;然后他也真的放上去了。再看那些照片&#xff0c;拍出来的效果都不咋样…

使用use index优化sql查询

转自&#xff1a;http://www.cnblogs.com/edwardlost/archive/2010/12/31/1923105.html 先看一下arena_match_index的表结构&#xff0c;大家注意表的索引结构 CREATE TABLE arena_match_index ( tid int(10) unsigned NOT NULL DEFAULT 0, mid int(10) unsigned NOT NULL …

中ridge_10种线性代数在数据科学中的强大应用(内附多种资源)

原文选自 | Analytics Vidhya作者 | Khyati Mahendru本文转载自 TalkingData数据学堂 &#xff0c;未经允许禁止转载本文摘要线性代数为各种各样的数据科学算法和应用提供支持在这里&#xff0c;我会向您介绍通过线性代数帮助您成为更好的数据科学家的10种实际应用我们已将这些…

排序算法之冒泡排序(JAVA)

//冒泡排序算法 平均时间复杂度 O(n*n) 稳定的排序算法 下面的是改进版的冒泡排序算法&#xff0c;使用exchange 标志位进行控制 public class bubbleSort { public static void bubbleSort(int[] data) { int i 0; int j 0; int tmp 0; int len …

C语言中变量的储存类别

C语言中变量的储存类别C语言中变量的储存类别1.动态存储方式与静态动态存储方式&#xff1a;从变量值存在的作时间&#xff08;即生存期&#xff09;角度来分&#xff0c;可以分为静态存储方式和动态存储方式。静态存储方式&#xff1a;是指在程序运行期间分配固定的存储空间的…

语言与golang语言运行速度_Golang语言情怀第13期 Go 语言设计模式 介绍

设计模式是什么俗话说&#xff1a;站在别人的肩膀上&#xff0c;我们会看得更远。设计模式的出现可以让我们站在前人的肩膀上&#xff0c;通过一些成熟的设计方案来指导新项目的开发和设计&#xff0c;以便于我们开发出具有更好的灵活性和可扩展性&#xff0c;也更易于复用的软…

blog发布测试

blog发布测试转载于:https://www.cnblogs.com/aj407blogs/p/9736120.html

字符串2在字符串1中第一次出现的位置strstr()

//字符串2在字符串1中第一次出现的位置&#xff0c;采用遍历的思想&#xff0c;移动str1的位置与str2进行匹配char *strstr(const char *str1, const char *str2) {int i 0;if (NULL str1){return NULL;}if (NULL str2){return (char *)str1;}if (*str2 ! \0){while (*str1 …