当前位置:首页 > 编程笔记 > 正文
已解决

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

来自网友在路上 195895提问 提问时间:2023-11-22 20:15:57阅读次数: 95

最佳答案 问答题库958位专家为你答疑解惑

当你考虑开发现代化、高效且可扩展的网站和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 makemigrationspython 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'] = 10request.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 Viewclass 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.getself.request = requestself.args = argsself.kwargs = kwargs# 调用dispatch方法,按照不同请求方式调用不同请求方法return self.dispatch(request, *args, **kwargs)...省略代码...# 返回真正的函数视图return viewdef 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_allowedreturn 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_ipdef 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. 执行结果
initbefore 视图==index==after 视图

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

二、MiddlewareMixin源码参考

class MiddlewareMixin(object):def __init__(self, get_response=None):self.get_response = get_responsesuper(MiddlewareMixin, self).__init__()def __call__(self, request):response = Noneif 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 视图 2after 视图

结论

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

模板

未完待续 下一期下一章

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

查看全文

99%的人还看了

猜你感兴趣

版权申明

本文"【Django使用】4大模块50页md文档,第4篇:Django请求与响应和cookie与session":http://eshow365.cn/6-41943-0.html 内容来自互联网,请自行判断内容的正确性。如有侵权请联系我们,立即删除!