【Django使用】4大模块50页md文档,第4篇:Django请求与响应和cookie与session

news2024/12/29 19:44:10

当你考虑开发现代化、高效且可扩展的网站和Web应用时,Django是一个强大的选择。Django是一个流行的开源Python Web框架,它提供了一个坚实的基础,帮助开发者快速构建功能丰富且高度定制的Web应用

Django全套笔记地址: 请移步这里


共 10 章,31 子模块


请求与响应

学习目标

  • 掌握request对象使用
  • 掌握response对象使用
  • 掌握Django中cookie的使用
  • 掌握Django中session的使用

Session

一、Session介绍

  1. sessioncookie对比

    1. cookie是在浏览器端保存键值对数据,而session是在服务器端保存键值对数据
    2. 重要敏感的数据(银行卡账号,验证码,余额等),建议存储在服务器端,不能通过cookie保存到浏览器
    3. session 的使用依赖 cookie
  2. Django中session数据的保存

    1. 生活例子

    session模块

    1. session键值对数据保存

    session模块

    1. session数据默认保存在django项目的一张数据库表中(表名为:django_session),保存格式如下:

    session模块

    • 不同的用户使用各自不同的浏览器,可以认为:一个浏览器代表一个用户
    • 【重要】表中一条记录,保存着一个浏览器(用户)所有的session键值对数据
    • 【重要】sessionid 是什么: 浏览器标识(用户标识),代表着一个用户,通过sessionid 可以找到该用户所有的session键值对数据

二、Session使用

  1. 开启session功能【默认已经开启】

django封装了session模块,用来简化session数据操作。请参见settings.py 配置文件中session配置:

INSTALLED_APPS = [
     ...
     # 默认导入了django自带的session模块
     'django.contrib.sessions',
 ]

 MIDDLEWARE = [
     ...
     # 开启session中间件
     'django.contrib.sessions.middleware.SessionMiddleware',
 ]
  1. 生成django项目默认的数据库表

    1. session数据默认保存在django项目的一张数据库表中(表名为:django_session)
    2. 在保存session数据库前,需要先生成django项目默认的数据库表
    3. 如何生成: 打开终端,并进入到项目根目录下,再执行以下2个命令生成数据库表:
    python manage.py makemigrations
     python manage.py migrate
    
  2. session数据操作

request.session属性:类型为 django.contrib.sessions.backends.db.SessionStore

  • 保存session数据(键值对
request.session['键']=
  • 读取session数据
request.session.get('键', 默认值)
  • 删除命令


# 删除一个sessoin键值对(注意:键不存在会报错 `KeyError`)


del request.session['键']

# 清除当前访问用户所有的session数据
request.session.flush()  # 删除一条表记录
request.session.clear()  # 清空字段中的session键值对数据
  • 设置session数据有效时间; 如果不设置,默认过期时间为两周
request.session.set_expiry(value)
  * 如果value是一个整数,则 session数据 将在value秒没有活动后过期
  * 如果value为0,则 session数据 将在用户 **关闭浏览器时过期**
  * 如果value为None,则 session数据 将在 **2周后过期**

三、案例

  • 需求:

    • 使用session保存 登录用户名 和 验证码:
    • 访问 http://127.0.0.1:8000/set_session 界面时,保存session数据
    • 访问 http://127.0.0.1:8000/get_session 界面时,读取session数据
  • 实现参考

  
  
# url配置
  
  
  url(r'^set_session$', views.set_session),
  url(r'^get_session$', views.get_session),

  # 视图函数
  def set_session(request):
      """保存session键值对数据"""
      request.session['user_id'] = 10
      request.session['user_name'] = 'admin'
      return HttpResponse('保存session成功')

  def get_session(request):
      """读取session键值对数据"""
      user_id = request.session.get('user_id')
      user_name = request.session.get('user_name')
      text = 'user_id = %s, user_name = %s' % (user_id, user_name)
      return HttpResponse(text)

测试:保存结果,需要作base64解码

session模块

四、保存session到redis中

使用第三方包 django-redis实现**

  1. 在虚拟环境下安装包
pip install django-redis==4.8.0
  1. 修改settings.py文件,新增如下选项:
  
  
# django项目的缓存配置
  
  
 CACHES = {
     "default": {
         "BACKEND": "django_redis.cache.RedisCache",
         "LOCATION": "redis://127.0.0.1:6379/1",
         "OPTIONS": {
             "CLIENT_CLASS": "django_redis.client.DefaultClient",
                 "PASSWORD": ""
         }
     }
 }

 # session数据缓存到Redis中
 SESSION_ENGINE = "django.contrib.sessions.backends.cache"
 SESSION_CACHE_ALIAS = "default"
  1. 测试: 启动Redis服务器,登录一次,再查看session是否有保存到 redis 1号数据库中

类视图

学习目标

  • 掌握Django中类视图的使用
  • 掌握类视图中使用装饰器
  • 能够使用类视图多继承和mixin扩展类

类视图

一、类视图

  • 发帖功能
  
  
# url配置
  
  
  urlpatterns = [
      url(r'^post$', views.post),            # 显示发帖界面
      url(r'^do_post$', views.do_post),      # 执行发帖操作
  ]

  # 视图
  def post(request):
      """get请求: 显示发帖界面"""
      return render(request, 'post.html')

  def do_post(request):
      """post请求: 执行发帖操作"""
      title = request.POST.get('title')
      content = request.POST.get('content')
      return HttpResponse('发帖:title=%s, content=%s' % (title, content))
  • 通过一个URL和视图同时实现登录功能的 GETPOST 请求(注意:可能还有PUT DELETE等);
  
  
# url配置
  
  
  urlpatterns = [
      url(r'^post$', views.post),            # 发帖功能
  ]

  # 视图
  def post(request):
      """发帖功能"""
      if request.method == 'GET':
          # get请求: 显示发帖界面
          return render(request, 'post.html')
      else:
          # post请求: 执行发帖操作
          title = request.POST.get('title')
          content = request.POST.get('content')
          return HttpResponse('发帖:title=%s, content=%s' % (title, content))
  • 类视图 实现

    • 以函数的方式定义的视图称为函数视图

    • 在Django中还可以通过类来定义一个视图,称为类视图

    • 类视图 的使用

      1. 定义一个类,继承Django提供的View
      from django.views.generic import View
      
       class PostView(View):
      
           def get(self, request):
               """get请求: 显示发帖界面"""
               return render(request, 'post2.html')
      
           def post(self, request):
               """post请求: 执行发帖操作"""
               # 代码简略
               return HttpResponse('执行发帖操作')
      

​ 2. 调用类视图的 as_view() 方法配置url

urlpatterns = [
    ...

    # 类视图注册

    url(r'^post2$', views.PostView.as_view()),
]

  • 类视图优点:对于函数视图代码可读性和复用性更好

二、类视图原理

@classonlymethod
def as_view(cls, **initkwargs):
    """
    Main entry point for a request-response process.
    """
    ...省略代码...

    def view(request, *args, **kwargs):
        self = cls(**initkwargs)
        if hasattr(self, 'get') and not hasattr(self, 'head'):
            self.head = self.get
        self.request = request
        self.args = args
        self.kwargs = kwargs
        # 调用dispatch方法,按照不同请求方式调用不同请求方法
        return self.dispatch(request, *args, **kwargs)

    ...省略代码...

    # 返回真正的函数视图
    return view

def dispatch(self, request, *args, **kwargs):
    # Try to dispatch to the right method; if a method doesn't exist,
    # defer to the error handler. Also defer to the error handler if the
    # request method isn't on the approved list.
    if request.method.lower() in self.http_method_names:
        handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
    else:
        handler = self.http_method_not_allowed
    return handler(request, *args, **kwargs)

三、类视图使用装饰器

1. 函数视图使用装饰器

需求: 实现禁止ip黑名单访问发帖界面。 解决: 可以通过在视图函数中使用装饰器实现,如下

  1. 为函数视图定义一个装饰器(在设计装饰器时,基本都以函数视图作为考虑的被装饰对象)
def check_ip(view_fun):
     """装饰器:禁止黑名单ip访问"""
     def wrapper(request, *args, **kwargs):
         # 在视图函数执行前做额外的操作:
         # 禁止ip黑名单访问
         IP = request.META.get('REMOTE_ADDR')
         if IP in ['192.168.210.160']:
             return HttpResponse('IP禁止访问')
         return view_fun(request, *args, **kwargs)
     return wrapper
  1. 给视图函数进行装饰
@check_ip
 def post(request):
     """GET请求: 显示发帖界面"""
     return render(request, 'post.html')

**或者:**也可以在URL中,通过方法调用的方式添加装饰器

urlpatterns = [
     ...
     # 发帖功能
     url(r'^post$', check_ip(views.post))
 ]
  • 问题:代码可读性差,只看视图,不知道它添加了装饰器


2. 类视图中使用装饰器

方案一:在路由中添加

```python
urlpatterns = [
    ...
    # 发帖功能
    url(r'^post2$', check_ip(views.PostView.as_view()))
]


**方案二:在类视图中添加**

注意:**不能直接给类视图的方法添加装饰器**,需要使用**method_decorator**将其转换为适用于类视图方法的装饰器。

```python
  
  
# 方式二
  
  
  
  
# @method_decorator(check_ip, name='get')  # 为特定的请求方法添加
  
  
  
  
# @method_decorator(check_ip, name='dispatch')    # 为所有的请求方法添加
  
  
class PostView(View):

    # 给所有的http方法都添加装饰器
    # @method_decorator(check_ip)
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

    # 方式一
    @method_decorator(check_ip)
    def get(self, request):
        """get请求:显示发帖界面"""
        return render(request, 'post2.html')

    def post(self, request):
        """post请求:执行发帖操作"""
        # 代码简略
        return HttpResponse('处理发帖操作')

**说明: 关于method_decorator装饰器作用:**为函数装饰器补充第一个self参数,以便让装饰器能应用到方法中。


3. 类视图多继承 & Mixin扩展类

使用面向对象多继承的特性,可以通过定义父类(作为扩展类),在父类中定义想要向类视图补充的方法,类视图继承这些扩展父类,便可实现代码复用。

定义的扩展父类名称通常以Mixin结尾。

举例如下:

class ListModelMixin(object):
    """
    list扩展类
    """
    def list(self, request, *args, **kwargs):
        print('查询多条数据')
        ...

class CreateModelMixin(object):
    """
    create扩展类
    """
    def create(self, request, *args, **kwargs):
        print('新增一条数据')
        ...

class DepartmentView(CreateModelMixin, ListModelMixin, View):
    """
    同时继承两个扩展类,复用list和create方法
    """
    def get(self, request):
        self.list(request)
        ...

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

class EmployeeView(CreateModelMixin, View):
    """
    继承CreateModelMixin扩展类,复用create方法
    """
    def post(self, request):
        self.create(request)
        ...

中间件

学习目标

  • 掌握Django中间件的使用

中间件

  • 装饰器:不在改变原有函数的前提下,在函数调用之前或之后执行额外的操作

  • Django中间件:

    • 一个轻量级、底层的插件系统,用于在视图函数调用之前或之后执行额外操作,在全局上修改Django的输入或输出;

官方文档–中间件

一、中间件使用

image

  1. 定义中间件类: 通过继承Django的MiddlewareMixin扩展类实现:

    • __init__(self, get_response=None)

      • 服务器启动,初始化中间件类时被调用,只执行一次
    • process_request(self, request):

      • 在视图执行之前调用,注意:该方法可以返回None或者response对象,如果返回response对象,则视图函数就不会再执行了
    • process_response(self, request, response):

      • 在视图执行之后调用,必须返回 response 对象
  2. setting.py文件中的MIDDLEWARE中注册

案例:

  1. 定义好中间件: 在项目中新建一个middlewares.py文件,然后在该文件中定义中间件类:
class MyMiddleware(MiddlewareMixin):

     def __init__(self, get_response=None):
         super().__init__(get_response)
         print('init')

     def process_request(self, request):
         print('before 视图')
         # 注意:可以返回None或者response对象,如果返回response对象,则视图函数就不会再执行了

     def process_response(self, request, response):
         print('after 视图')
         return response
  1. 在settings.py 文件中添加注册中间件
MIDDLEWARE = [
     'django.middleware.security.SecurityMiddleware',
     ...

     'middlewares.MyMiddleware',  # 注册中间件
 ]
  1. 定义一个视图进行测试
def index(request):
     print('==index==')
     return HttpResponse('hello django')
  1. 执行结果
init
 before 视图
 ==index==
 after 视图

注意:调试模式下 __init__ 方法会执行两次

二、MiddlewareMixin源码参考

class MiddlewareMixin(object):
    def __init__(self, get_response=None):
        self.get_response = get_response
        super(MiddlewareMixin, self).__init__()

    def __call__(self, request):
        response = None
        if hasattr(self, 'process_request'):
            response = self.process_request(request)
        if not response:
            response = self.get_response(request)
        if hasattr(self, 'process_response'):
            response = self.process_response(request, response)
        return response

三、多个中间件的执行顺序

image

示例

  1. 再定义一个中间件类
class MyMiddleware2(MiddlewareMixin):

     def __init__(self, get_response=None):
         super().__init__(get_response)
         print('init 2')

     def process_request(self, request):
         print('before 视图 2')

     def process_response(self, request, response):
         print('after 视图 2')
         return response
  1. 注册
MIDDLEWARE = [
     'django.middleware.security.SecurityMiddleware',
     ...
     'middlewares.MyMiddleware',  # 注册中间件
     'middlewares.MyMiddleware2',  
 ]
  1. 执行结果
before 视图
 before 视图 2
 ==index==
 after 视图 2
 after 视图

结论

  • 对于视图之前执行的 process_request 方法, 注册的中间件先执行
  • 对于视图之后执行的 process_response 方法, 注册的中间件先执行

模板

未完待续 下一期下一章

全套笔记直接地址: 请移步这里

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

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

相关文章

动态规划十大经典问题

动态规划十大经典问题 动态规划十大经典问题 数塔取数问题、矩阵取数问题、最大连续子段和、最长递增子序列、最长公共子序列、最长公共子串、最短编辑距离、背包问题、正整数分组、股票买卖问题。 1、数塔取数问题 // 数塔取数问题 public static int dataTowerAccess(int[]…

一文读懂 Linux 网络 IO 模型

文章目录 1.从一个问题说起2.多进程模型3.多线程模型4.I/O 多路复用5.select、poll、epoll 的区别?5.1 select5.2 poll5.3 epoll5.4 两种事件触发模式 参考文献 1.从一个问题说起 互联网发展历史上,曾经有一个著名的问题:C10K 问题。 C 是 …

5-4计算一串字符的空格数字字符其他

#include<stdio.h> int main(){char c;int space0;//空格int letters0;//英文字母int numbers0;//数字int others0;//其他字符printf("请输入一行字符&#xff1a;");while((cgetchar())!\n)//获取字符的内容&#xff0c;到\n停止{if(c>a&&c<z|…

AR眼镜方案—单目光波导AR智能眼镜

光波导技术是一项具有前沿意义的技术&#xff0c;它能够将光线反射180度&#xff0c;使得眼镜框架内置的MicroLED屏幕的图像通过多次反射与扩散后准确地传递到人眼中。采用MicroLED显示技术的AR智能眼镜不仅体积显著缩小&#xff0c;屏幕只有0.68英寸大小&#xff0c;并且还能够…

【PostgreSQL】解决PostgreSQL时区(TimeZone)问题

问题描述 最近在使用PostgreSQL中&#xff0c;对行记录进行设置创建时间&#xff08;created_time&#xff09;时&#xff0c;出现了设置了now()时间而数据库中写入的数据是不一致的数据。 eg&#xff1a; insert into dept ( created_at, updated_at) VALUES (now(),now())…

Spring框架学习 -- 核心思想

目录 (1) Spring是什么? (2) 什么是IOC容器? (3) 从传统开发认识spring (4) 这种传统开发的缺陷 (5)解决传统开发中的缺陷 (6) 对比总结规律 (7) 理解IOC 创作不易多多支持 (1) Spring是什么? 我们常说的Spring的全称是: Spring Framework(Spring框架), 它是一个开源…

【经验之谈·高频PCB电路设计常见的66个问题】

文章目录 1、如何选择PCB 板材&#xff1f;2、如何避免高频干扰&#xff1f;3、在高速设计中&#xff0c;如何解决信号的完整性问题&#xff1f;4、差分布线方式是如何实现的&#xff1f;5、对于只有一个输出端的时钟信号线&#xff0c;如何实现差分布线&#xff1f;6、接收端差…

微信小程序记住密码,让登录解放双手

密码是用户最重要的数据&#xff0c;也是系统最需要保护的数据&#xff0c;我们在登录的时候需要用账号密码请求登录接口&#xff0c;如果用户勾选记住密码&#xff0c;那么下一次登录时&#xff0c;我们需要将账号密码回填到输入框&#xff0c;用户可以直接登录系统。我们分别…

win11,安装python,pip,和opencv

1,安装python 在应用商店&#xff0c;输入python&#xff0c;下载安装 2&#xff0c;安装pip 在cmd中&#xff0c;输入pip install SomePackage&#xff0c;安装某一个版本的pip 3,安装opencv 在cmd中&#xff0c;输入 pip3 install opencv-contrib-python -i https://pyp…

css 实现鼠标上移添加下划线

效果图 实现代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-wi…

Linux网络驱动

Linux 网络设备驱动结构 网络协议接口层向网络层协议提供统一的数据包收发接口&#xff0c;这一层使得上层协议独立于具体的设备网络设备接口层向协议接口层提供统一的用于描述具体网络设备属性和操作的结构体net_device&#xff0c;该结构体是设备驱动功能层中各函数的容器设备…

力扣C++学习笔记——C++ 给vector去重

要使用std::set对std::vector进行去重操作&#xff0c;您可以将向量中的元素插入到集合中&#xff0c;因为std::set会自动去除重复元素。然后&#xff0c;您可以将集合中的元素重新存回向量中。以下是一个示例代码&#xff0c;演示如何使用std::set对std::vector进行去重&#…

阵列 MEMS-IMU的解算系统

使用飞速发展的硅半导体工艺制成的微机械电子系统&#xff08;Micro Electro Mechanical System&#xff0c;MEMS&#xff09;具有体积小、成本低、重量轻、低功耗等诸多优势。MEMS-IMU&#xff08;Inertial Measurement Unit, IMU&#xff09;构成的捷联惯导系统可以应用到无人…

关闭bitlocker加密

windows11的笔记本电脑买回来发现分驱都处于bitlocker状态&#xff0c;上网上搜索都是说进入控制面板的安全项进行关闭&#xff0c;包括去搜索栏搜索“管理 BitLocker”&#xff0c;对搜索出来的项打开&#xff0c;经过试验&#xff0c;它们进入的是同一个位置&#xff0c;只有…

高防CDN如何预防攻击?

现在网络攻击事件越来越多&#xff0c;而且愈发凶猛&#xff0c;为了保障互联网业务能稳定正常的运行&#xff0c;市场上出现了很多高防产品&#xff0c;例如高防服务器、高防IP、高防CDN等等。其中究竟高防CDN怎么防攻击&#xff0c;能防哪些攻击&#xff1f;高防CDN如何实现防…

HarmonyOS基础组件之Button三种类型的使用

简介 HarmonyOS在明年将正式不再兼容Android原生功能&#xff0c;这意味着对于客户端的小伙伴不得不开始学习HarmonyOS开发语言。本篇文章主要介绍鸿蒙中的Button使用。 HarmonyOS中的Button相较于Android原生来说&#xff0c;功能比较丰富&#xff0c;扩展性高&#xff0c;减…

线程(线程基本概念、java实现多线程、使用多线程、线程的生命周期、线程同步、线程死锁)

&#xff08;一&#xff09;线程基本概念 一、 程序, 进程, 线程的概念 程序: 使用某种语言编写一组指令(代码)的集合,静态的 进程: 运行的程序,表示程序一次完整的执行, 当程序运行完成, 进程也就结束了 个人电脑: CPU 单个, 双核, CPU的时间分片, 抢占式 每个独立执行的程…

【20年扬大真题】编写对数组求逆的递归算法

【20年扬大真题】 编写对数组求逆的递归算法 void swap(int* a, int* b) {int tmp *b;*b *a;*a tmp; } void Ni(int arr[],int left,int right) {if (left > right) {return;}swap(&arr[left], &arr[right]);Ni(arr, left 1, right - 1); } int main() {int ar…

威视佰科荣获:2023年“AI天马”高成长性企业

11月14日下午&#xff0c;2023年度“AI天马”认定评审会顺利召开。落实《深圳经济人工智能产业促进条例》&#xff0c;加快推进智能机器人、智能传感器、智能网联汽车、智能终端、脑科学和类脑智能等人工智能相关产业发展&#xff0c;加速AI产业化和产业AI化进程&#xff0c;持…

对象分配规则

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一份大厂面试资料《史上最全大厂面试题》&#xff0c;Springboot、微服务、算法、数据结构、Zookeeper、Mybatis、Dubbo、linux、Kafka、Elasticsearch、数据库等等 …