美文网首页
Python(五十四)cookie与session

Python(五十四)cookie与session

作者: Lonelyroots | 来源:发表于2022-02-10 23:04 被阅读0次

从2021年9月2日发文至今,Python系列(包括代码在内)共计103089个字、五十四篇!

小知识科普:

在pycharm的Terminal中安装模块如果出现这个问题:ModuleNotFoundError: No module named 'pip'(或者各种各样的问题),我建议先采用这种方式来安装库,因为我的python解释器是在F:\learning_records\SoftwareSpace\Python3.7这个路径下方的,所以我在Windows的cmd命令行窗口用这种方式(如下图):F:\learning_records\SoftwareSpace\Python3.7>python.exe -m pip install requests [-i https://pypi.douban.com/simple]:中括号内的为国内镜像源,可以加快速度,可用可不用。

如果遇到这种ImportError:cannot import name 'views'的问题,不妨先看下右上角的运行文件名称,修改下即可!


大家知道客户端和服务器是怎么记录登录状态的呢?
如果你不知道,那请阅读这篇文章,因为它将带你走近并解决这个问题!

1.HttpRequest对象

服务器接收到http协议的请求后,会根据报文创建HttpRequest对象,视图函数的第一个参数是HttpRequest对象在django.http模块中定义了HttpRequest对象的API。

2.GET和POST请求

get_post/views.py:

# (十、cookie与session)

import os
from django.shortcuts import render
from django.http import HttpResponse,JsonResponse
from django.views import View
from Myblog15_16.settings import MEDIA_ROOT

# Create your views here.

def index(request):
    print(request)
    print(request.path)     # 路由
    print(request.method)       # 提交方式
    print(request.encoding)     # 编码为None,则为浏览器的默认编码
    print(request.get_host())   # ip加端口
    print(request.get_port())   # 端口

    return render(request,'get_post/index.html')

# get一般用于渲染页面
def get_test(request):
    print(request.method)
    # user = request.GET.get('user')
    # pwd = request.GET.get('pwd')      # get方法只能用于一对一获取值
    # print(user,pwd)
    hobbies = request.GET.getlist('hobby')      # getlist方法可以用于一对多获取值
    print(hobbies)

    return HttpResponse('数据提交成功!')

# post一般用于数据提交,相比于get更加地安全!
def post_test(request):
    print(request.method)
    user = request.POST.get('user')
    pwd = request.POST.get('pwd')
    print(user,pwd)

    return HttpResponse('数据提交成功!')

{#(十、cookie与session)#}

{% comment %}{#get测试#}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>请求与响应</title>
</head>
<body>
<form action="{% url 'get_test' %}" method="get">
    <input type="text" name="user" placeholder="请输入用户名"><br>
    <input type="password" name="pwd" placeholder="请输入密码"><br>
    <button type="submit">提交</button>
</form>
</body>
</html>{% endcomment %}


{% comment %}{#post测试#}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>请求与响应</title>
</head>
<body>
<form action="{% url 'post_test' %}" method="post">
    {% csrf_token %}
    <input type="text" name="user" placeholder="请输入用户名"><br>
    <input type="password" name="pwd" placeholder="请输入密码"><br>

    <button type="submit">提交</button>
</form>
</body>
</html>{% endcomment %}

3.类视图

View类视图以请求方式为类方法:在对应的方式下面编写对应的逻辑函数。

blog/views.py:

# (十、cookie与session:类视图)
from django.views import View
from .models import BlogModel
from django.shortcuts import render, redirect, reverse

# 使用类视图,可以不需要get和post判断
class Blog_update(View):
    def get(self,request,blog_id):
        blog = BlogModel.objects.get(id=blog_id)
        return render(request,'blog/blog_edit.html',context={'blog':blog})

    def post(self,request,blog_id):
        # 获取文章标题
        new_title = request.POST.get('new_title')  # 这里的new_title需要和前端页面blog_edit里的标题input中的name值保持一致.
        # 获取文章内容
        new_content = request.POST.get('new_content')  # 这里的new_content需要和前端页面blog_edit里的内容input中的name值保持一致.
        BlogModel.objects.filter(id=blog_id).update(title=new_title,content=new_content)  # 这里的红变量名是数据库中的字段名称
        # 文章修改成功后,要转到文章列表页,展示所有文章.
        return redirect(reverse('blog_list'))

templates/blog/blog_edit.html:

{% extends 'blog/blog_base.html' %}

{% block title %}
    修改博客
{% endblock %}

{% block body %}
    <h1>修改博客</h1>
{% comment %}    <form action="{% url 'blog_edit' blog.id %}" method="post"> {% endcomment %}           {# 当不填写action提交路径时,默认提交到当前路径,所以这里写不写action都是可以的 #}
    <form action="{% url 'cls_update' blog.id %}" method="post">     {# (十、cookie与session:类视图) #}
        {#  csrf_token防止跨域请求  #}
        {% csrf_token %}
        新标题:<input type="text" id="new_title" name="new_title" value="{{ blog.title }}"><br>
        新内容:<textarea name="new_content" id="new_content" cols="20" rows="10">{{ blog.content }}</textarea>
        <button type="submit">确认修改</button>
    </form>
    <br>
    <a href="{% url 'blog_list' %}">返回列表页</a>
{% endblock %}

templates/blog/blog_list.html:

{% extends 'blog/blog_base.html' %}

{% block title %}
    博客显示
{% endblock %}

{% block body %}
    <h1>靓文展示页</h1>
    <table>
        <tr>
            <th width="80px">标题</th>
            <th>功能</th>
        </tr>
        {% for b in b_list %}
            <tr>
                <td style="text-align: center"><a href="{% url 'blog_detail' b.id %}">{{ b.title }}</a></td>
{% comment %}                <td><a href="{% url 'blog_edit' b.id %}">编辑</a>&emsp;<a href="{% url 'blog_delete' b.id %}">删除</a></td>{% endcomment %}
                <td><a href="{% url 'cls_update' b.id %}">编辑</a>&emsp;<a href="{% url 'blog_delete' b.id %}">删除</a></td>        {# (十、cookie与session:类视图) #}
            </tr>
        {% endfor %}
    </table>
    <br>
    <a href="{% url 'blog_index' %}">返回首页</a>
{% endblock %}

get_post/urls.py:

# (十、cookie与session)
from django.urls import path
from . import views

urlpatterns = [
    path('index/',views.index),
    path('get_test/',views.get_test,name='get_test'),
    path('post_test/',views.post_test,name='post_test'),
    path('upload/',views.Upload.as_view(),name='upload'),
    path('json_test/',views.json_test,name='json_test'),
]

View类视图的引用:在url.py中配置路由是通过as_view()

blog/urls.py:

from django.urls import path
from . import views

urlpatterns = [
    path('index/',views.index,name='blog_index'),
    path('cls_update/<blog_id>/',views.Blog_update.as_view(),name='cls_update'),      # 只要是使用类视图,就需要调用as_view()这个方法
]

4.文件上传

Django在处理文件上传的时候,文件数据被保存在了request.FILES
FILES中的每个键为<input type="file" name="" />中的name
设置文件的存储路径:
1.在项目根目录下static中创建media文件夹
2.图片上传后,会被保存到“/static/media/文件”

3.打开settings.py文件,增加media_root项

4.1.文件上传form表单中

FILES只有在请求的方法为POST且提交的<form>带有enctype="multipart/form-data" 的情况下才会包含数据。否则,FILES 将为一个空的类似于字典的对象。

templates/get_post/index.html:

{#文件上传#}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>请求与响应</title>
</head>
<body>
<form action="{% url 'upload' %}" method="post" enctype="multipart/form-data">      {# enctype="multipart/form-data"如果不设置,默认不允许文件上传 #}
    {% csrf_token %}
    <input type="text" name="user" placeholder="请输入用户名"><br>
    <input type="password" name="pwd" placeholder="请输入密码"><br>
    <input type="file" name="file"><br>
    <button type="submit">提交</button>
</form>
</body>
</html>

4.2.文件上传视图函数

get_post/views.py:

# (十、cookie与session)

import os
from django.shortcuts import render
from django.http import HttpResponse
from django.views import View
from Myblog15_16.settings import MEDIA_ROOT

# 文件上传类视图
class Upload(View):
    def get(self,request):
        return render(request,'get_post/index.html')

    def post(self,request):
        # 获取文件需要使用FILES的方法
        f = request.FILES.get('file')       # 获取文件
        f_name = os.path.join(MEDIA_ROOT,f.name)        # 拼接路径和文件名
        with open(f_name,'wb+') as fp:
            for i in f.chunks():        # 读取文件的内容,
            # read()是从文件中读取整个上传的数据,如果文件过大,就会读到内存中,占用系统内存
            # chunks()如果上传的文件足够大时,就会分块上传数据
                fp.write(i)
        return HttpResponse('文件上传完毕!')

5.HttpResponse对象

5.1.HttpResponse的子类:

返回数据的响应函数有:
HttpResponse() 返回简单的字符串对象
render() 渲染模板
redirect() 重定向

JsonResponse() 返回json数据

其中JsonResponse:

  • 帮助用户创建JSON编码的响应
  • 参数data是字典对象
  • JsonResponse的默认Content-Type为application/json

get_post/views.py:

# (十、cookie与session)

from django.http import JsonResponse

def json_test(request):
    # JSON格式的数据必定是双引号
    return JsonResponse({'name':'chenhong','age':18})        # 这里是键值对的字典,通过路由在网页上访问时,才是一个JSON格式的数据

6.Http协议

HTTP(超文本传输协议)是一个应用层协议,由请求和响应构成,是一个标准的客户端服务器模型,且HTTP是一个无状态的协议。

7.浏览器中的cookie

虽然cookie可以保存状态,但注意不要存储敏感信息。想要了解状态保持的另一种方式,请关注Python系列(五十五)的内容哦!
注意:设置cookie值以及删除cookie值都是response对象的操作,而获取cookie是从requeset相应中获得的.

get_post/views.py:

import datetime
from django.http import HttpResponse

# 设置cookie
def set_ck(request):
    response = HttpResponse('设置cookie')
    # response.set_cookie('name','django')    # 不设置过期时间的情况下,关闭浏览器就过期了
    # response.set_cookie('name','django',max_age=30)   # 设置过期时间,以秒为单位,30s后过期
    response.set_cookie('name','django',expires=datetime.datetime(2022,2,25))       # 指定过期时间
    return response

# 获取cookie
def get_ck(request):
    ck = request.COOKIES
    value = ck.get('name')
    if value:
        return HttpResponse(f'欢迎{value}回来!')
    return HttpResponse('请您先登录')

# 删除cookie
def del_ck(request):
    response = HttpResponse('删除cookie')
    response.delete_cookie('name')
    return response

get_post/urls.py:

# (十、cookie与session)
from django.urls import path
from . import views

urlpatterns = [
    path('set_ck/',views.set_ck,name='set_ck'),
    path('get_ck/',views.get_ck,name='get_ck'),
    path('del_ck/',views.del_ck,name='del_ck'),
]

文章到这里就结束了!希望大家能多多支持Python(系列)!六个月带大家学会Python,私聊我,可以问关于本文章的问题!以后每天都会发布新的文章,喜欢的点点关注!一个陪伴你学习Python的新青年!不管多忙都会更新下去,一起加油!

Editor:Lonelyroots

相关文章

网友评论

      本文标题:Python(五十四)cookie与session

      本文链接:https://www.haomeiwen.com/subject/rfgokrtx.html