• 一个初学者的辛酸路程-继续Django


    问题1:HTTP请求过来会先到Django的那个地方?
    先到urls.py  ,里面写的是对应关系,1个URL对应1个函数名。
    如果发URL请求过来,到达这里,然后帮你去执行指定的函数,函数要做哪些事?
    给客户端浏览器返回字符串,只不过返回形式不一样。
     
    路由系统:  url.py
    视图函数 : views.py
    -数据库操作   models.py
    -模板引擎渲染
    • -Http Reponse(字符串)
    • -render(request,'/path/a.html')
    • 如果有特殊的标签怎么办?
    • 如果遇到特殊的标签比如{{ name }} ,他就会把它替换掉,会把name对应的root替换掉
    • -render(request,'/path/a.html',{‘name’: ‘root’})
    流程如下:
    请求到来之后到达视图函数,视图函数帮助处理返回内容,处理阶段,会用到模板引擎渲染,完事后返回给用户。
    一、数据库操作的增删改查
    实例: 基本curd
    1、数据库设计
    id   hostname    ip   port  status
    2、在数据库生成表
    3、请求过来,先去处理请求,写上url ,
    去数据库拿数据返回给用户。
     
    功能实现:
    预备阶段:
    创建project   
    • django-admin  startproject mysite ,
    创建app 
    •   cd mysite   python manage.py startapp  app01,
    配置模板路径
    •  settings.py里面找TEMPLATE里有个DIRS:【os.path.join(BASE_DIR,'templates'),】,
    配置静态文件
    •  跟上一样,settings.py里
    • STATICFILES_DIRS = (
    • os.path.join(BASE_DIR,'static'),
    • )
    URL:
    a.    /servers   ==>对应函数server处理
    views:
    a  数据库获取数据
    • 自动: 先创建类==>相当于数据库的表
    • 类里的字段代表数据库的列
    • class  UserInfo:
    • username = 字符串
    • pwd = 字符串
    • age = 数字
     
    写一个:
    servers.html
    1. <body>
    1.     <h1>我是大王</h1>
    1.     <h3>{{ k1 }}</h3>
    1.     <h3>{{ k2 }}</h3>
    1. </body>
    此时我的views.py写法如下:
    1. def servers(request):
    1.    # return HttpResponse('OK')
    1.    # return render(request,'servers.html')
    1.    #  return render(request,'server.tpl',{})
    1.    #  return redirect('http://www.baidu.com')
    1.    #  return render(request,'server.txt')
     
    1.    return render(
    1.        request,
    1.        'servers.html',
    1.            {
    1.                'k1':'root',
    1.                'k2':123,
    1.                'k3':[11,22,33],
    1.                'k4':{'name':'alex','age':15},
    1.            }
    1.    )
     
    用户发来请求,要把所有的数据列出来。
     
    跟数据库相关:
    让Django控制那些APP能够生产库和表,这里要在settings.py 把APP注册进入,写哪个就创建哪个的表,不写数据库的表生成不了。
     
    进入app01修改models.py
    先创建类:
    1. class UserInfo(models.Model):
    1.     nid = models.AutoField(primary_key=True)
    1.     username = models.CharField(max_length=32)
    1.     pwd = models.CharField(max_length=64)
    1.     age = models.IntegerField()
    第2个是自增,3是字符串,4也是字符串,5是数字
     
    然后执行:
    1. python manage.py makemigrations
    1. python manage.py migrate
    执行完了以后呢,就会生成这么额一个数据,在db.sqlite3里面生成表
     
    这里需要注意事项:
    1、settings.py要注册app名字
    2、如果是链接mysql,需要手动创建库名,然后在settings.py中配置。
    • 把里面的注释掉,添加下面即可。
    • django默认链接mysql用的是mysqlDb,这个模块只在Python2有,在Python3没有
    • 所以需要吧mysqlDB改成pymysql。
    • 就有一个换的过程,如何换?
    • 放在django目录下面有一个__init__.py,如下图所示:
    • 那么他就会自动修改默认为pymysql来链接数据库。
     
     
     
    类===表
    字段==列
    对象==一行数据
     
    下面手动数据一些数据,来做一个数据库获取所有并展示的例子:
    步骤1:
    手动插入数据如下:
     
    步骤2:
    修改view函数
    1. from app01 import models
    1. def servers(request):
    1.     server_list = models.UserInfo.objects.all()
    1.     #得到的是一个对象列表[userinfo(id=1,username=root,age=18),..]
    1.     # for row in server_list:
    1.         # print(row.nid,row.username,row.pwd,row.age)
    1.     return render(request,'servers.html',{'server_list':server_list})
    步骤3:
    修改HTML
    1. <!DOCTYPE html>
    1. <html lang="en">
    1. <head>
    1.     <meta charset="UTF-8">
    1.     <title>Title</title>
    1. </head>
    1. <body>
    1.     <h1>服务器列表</h1>
    1.     <ul>
    1.         {% for row in server_list %}
    1.             <li>{{ row.nid }}-{{ row.username }}-{{ row.pwd }}-{{ row.age }}</li>
    1.         {% endfor %}
    1.     </ul>
    1. </body>
    1. </html>
    最后效果如下:
     
    流程如下:
    请求到来URL,对应关系,URL对应函数,函数执行数据库操作,用户返回内容,有返回字符串和返回并渲染。
     
    扩展:
    页面点击添加按钮跳转,加入a标签
    一般情况下,GET请求一般来说就是获取看到这个页面,点击也可以往URL提交,只不过method换成post了。
    只有post的时候才能获取数据,所以要做一个判断。
    用户发过来的数据都在request.POST里面
     
    实现功能:跳转到新的页面,增加一条数据后,在跳转到原页面
     
    修改views.py
    1. def add_user(request):
    1.     if request.method == 'GET':
    1.         return render(request,'add_user.html')
    1.     elif request.method == 'POST':
    1.         u = request.POST.get('user')
    1.         p = request.POST.get('pwd')
    1.         a = request.POST.get('age')
    1.         print(u,p,a)
    1.         #将数据插入数据库
    1.         #方法1
    1.         # obj = models.UserInfo(username=u,pwd=p,age=a)
    1.         # obj.save()
    1.         #方法2
    1.         models.UserInfo.objects.create(username=u,pwd=p,age=a)
    1.         return redirect('/users')
    新增add_user.html
    1. <!DOCTYPE html>
    1. <html lang="en">
    1. <head>
    1.     <meta charset="UTF-8">
    1.     <title>Title</title>
    1. </head>
    1. <body>
    1.     <form action="/add_user" method="POST">
    1.         <p><input type="text" name="user" placeholder="用户名"></p>
    1.         <p><input type="password" name="pwd" placeholder="密码"></p>
    1.         <p><input type="text" name="age" placeholder="年龄"></p>
    1.         <input type="submit" value="提交">
    1.     </form>
    1. </body>
    1. </html>
     
    在servers.html里面添加一个跳转a 标签
    1. <div>
    1.     <a href="/add_user">添加</a>
    1. </div>
     
     
    扩展:
    新增删除
     
    步骤1:
    URL
    1. url(r'^del_user$', views.del_user),
    步骤2:
    新增views.py文件
    1. def del_user(request):
    1.     nnid = request.GET.get('nid')
    1.     # models.UserInfo.objects.all().delete()#删除整个表数据
    1.     models.UserInfo.objects.filter(nid=nnid).delete()
    1.     return redirect('/users')
    步骤3,修改HTML文件
    1. <ul>
    1.     {% for row in server_list %}
    1.         <li>{{ row.nid }}-{{ row.username }}-{{ row.pwd }}-{{ row.age }}-<a href="/del_user?nid={{ row.nid }}">删除</a></li>
    1.     {% endfor %}
    1. </ul>
    实现效果:
    可以再页面上删除
     
     
    ===========分割线===========
    请求来了,先到URL,然后对应函数,去数据库拿数据,然后渲染,返回
     
     
    扩展,新增编辑
    步骤1:
    URL
    1. url(r'^edit_user$', views.edit_user),
     
    步骤2:
    新增views.py文件
    1. def edit_user(request):
    1.     if request.method == 'GET':
     
    1.         nnid = request.GET.get('nid')
    1.         #根据nnid获取单条数据
    1.         # v = models.UserInfo.objects.filter(nid=nnid)
    1.         v = models.UserInfo.objects.filter(nid=nnid).first()
    1.         #获取的是对象列表  [UserInfo(),],永远获取的是一个列表,不是对象,如下
    1.         #<QuerySet [<UserInfo: UserInfo object>]>
    1.         print(v.nid,v.username,v.pwd,v.age)
    1.         return render(request,'edit_user.html',{'obj':v})
    1.     elif  request.method == 'POST':
    1.         nnid = request.POST.get('nid')
    1.         u = request.POST.get('user')
    1.         p = request.POST.get('pwd')
    1.         a = request.POST.get('age')
    1.         #方法1
    1.         # obj = models.UserInfo.objects.filter(nid=nnid).first()
    1.         # obj.username = u
    1.         # obj.pwd = p
    1.         # obj.age = a
    1.         # obj.save()
    1.         models.UserInfo.objects.filter(nid=nnid).update(username=u,pwd=p,age=a)
    1.         return redirect('/users')
    步骤3:
    新增HTML
    1. <!DOCTYPE html>
    1. <html lang="en">
    1. <head>
    1.     <meta charset="UTF-8">
    1.     <title>Title</title>
    1. </head>
    1. <body>
    1.     <form action="/edit_user" method="POST">
    1.         <p style="display: none;"><input type="text" name="nid" placeholder="ID" value="{{ obj.nid }}"></p>
    1.         <p><input type="text" name="user" placeholder="用户名" value="{{ obj.username }}"></p>
    1.         <p><input type="password" name="pwd" placeholder="密码" value="{{ obj.pwd }}"></p>
    1.         <p><input type="text" name="age" placeholder="年龄" value="{{ obj.age }}"></p>
    1.         <input type="submit" value="提交">
    1.     </form>
    1. </body>
    1. </html>
     
    有点需要提到就是:
    在写urls.py里面,正确的URL写法如下:
    1. url(r'^edit_user$', views.edit_user),
     
    SEO看到这个
     
    会认为是个动态页面,权重会低一些,如果改成
     
    会认为是一个静态,权重会高点,便于搜索引擎优化。
    怎么让我写一个URL来匹配所有的呢?正则匹配有-d
     
    动态路由:
     
    接下来就写一个-的形式。为了利于SEO搜索引擎优化。
    我想写到一个只写1个URL匹配多个,正则表达式里面有一个-d,匹配数字
    1.  url(r'^edit_user-(d+).html$', views.edit_user),
    那么传递的时候也应该把这个数字获取到,不能以GET形式传,如果是?形式可以用GET
    但是,函数必须要拿到这个ID,如何传递呢?
    那就在函数里面在加一个参数
    1. def edit_user(request,a1):
    1.     print(a1)
    1.     return HttpResponse(a1)
    这个就是以URL的方式传了,而不是GET形式。注意上面的a1可以是任何
    如果有2个占位符,那么后面传参害的加个数字。
    1. def edit_user(request,a1,a2):
    1.     print(a1,a2)
    1.     return HttpResponse(a1+'--'+a2)
    1.     
    1.     
    1.     
    1.     
    1. url(r'^edit_user-(d+)-(d+).html$', views.edit_user),
     
    • 但是它这个是按照顺序传送的,通过这种方式也可以传值,但是呢,他是依赖顺序的。
     
    接下来我给正则表达式写个名字。
    ?P<n1>
    写法如下:
     
    正则表达式还是d+,我加上N1和N2说明函数里面必须有N1和N2,其他不行
    1. url(r'^edit_user-(?P<n1>d+)-(?P<n2>d+).html$', views.edit_user),
    函数变为
    1. def edit_user(request,n1,n2):
    1.     print(n1,n2)
    1.     return HttpResponse(n1+'--'+n2)
     
     
    这样传值跟位置没有关系了,叫做动态路由方式
    下面就是基于这个来进行修改为动态路由
     
    函数修改:
    1. def edit_user_new(request,nnid):
    1.     if request.method == 'GET':
    1.         obj = models.UserInfo.objects.filter(nid=nnid).first()
    1.         return render(request,'edit_user_new.html',{'obj':obj})
    1.     elif request.method == 'POST':
    1.         u = request.POST.get('user')
    1.         p = request.POST.get('pwd')
    1.         a = request.POST.get('age')
    1.         models.UserInfo.objects.filter(nid=nnid).update(username=u,pwd=p,age=a)
    1.         return redirect('/users')
    URL修改
    1. url(r'^edit_user_new-(?P<nnid>d+).html$', views.edit_user_new),
    HTML修改
    1. <body>
    1.     <h1>新</h1>
    1.     <form  method="POST" action="edit_user_new-{{ obj.nid }}.html">
    1. {#        <p style="display: none;"><input type="text" name="nid" placeholder="ID" value="{{ obj.nid }}"></p>#}==>这个就不需要了
    1.         <p><input type="text" name="user" placeholder="用户名" value="{{ obj.username }}"></p>
    1.         <p><input type="password" name="pwd" placeholder="密码" value="{{ obj.pwd }}"></p>
    1.         <p><input type="text" name="age" placeholder="年龄" value="{{ obj.age }}"></p>
    1.         <input type="submit" value="提交">
    1.     </form>
    1. </body>
    关键在第一行
     
     
    接着扩展,在URL里面加个name='nnn'  ,给URL 起一个别名,这样他就能反生一个URL
    代指的就是URL,这样就可以直接修改HTML,如下所示:
    我修改URL,让mmm对应的URL为add_user
    我在修改edit_user_new表单
     
    在浏览器访问,查看表单,发现,mmm已经映射为了add_user
     
     
     
    但是如果URL有个动态的值,就不能直接这么写了,要写成这样子
    1. <form  method="POST" action="{% url "nnn" nnid=obj.nid  %}">
     
    URL写成
    1. url(r'^edit_user_new-(?P<nnid>d+).html$', views.edit_user_new,name='nnn'),
    这样就通过别名直接反生URL了
     
    对于没有名字呢?直接加空格即可,最后总结为几个
     
    以后会通过这种反生出来‘
    别名理解就是,给一个URL 一个简称,这么长的东西由这个来代替。
     
    如果现在要写个平台,会有很多块,如果都放在1个project下面,要创建多个APP
     
    维护每一个,就相当于1个业务,如果有人想修改URL,第一个部门要配置,第二个也要在settings.py配置,但会存在出错。对于写程序,不应该这样弄,可以这么弄。在URL里面修改为
     
     
    1. url(r'^app01/',include('app01.urls')),
    1. url(r'^app02/',include('app02.urls')),
    1. url(r'^app03/',include('app03.urls')),
    这么做的意思就是,相当于,我在设置里规定,访问带了app01,那么
    把路由所有的关系放在app01里面,然后我在app01里面创建一个urls.py文件
    修改地方如下:
    1、修改全局的URL,如上
    1. url(r'^app01/',include('app01.urls')),
    1. url(r'^app02/',include('app02.urls')),
    2、每个APP里面新增urls
     
    3、修改函数
    4、页面测试访问
     
     
    小结:
    以后就把URL做了一个分发
     
     
    So
    URL这需要记住4点:
    1、一个URL对应1个函数,定死的
    2、URL存在正则表达式,对应函数,类似1批URL对应函数处理
    3、URL后面可以加别名,通过别名反生出URL
    4、对于URL说可以进行分发。(重点)
     
    视图函数
    return值
     
    获取请求信息:
    request.POST
    request.GET
    request.method
    request.FILES   通过它可以上传文件。
     
    具体做法,我在app01里面定义url和views函数
    1. url(r'^test$', views.test),
    定义函数
    1. def upload(request):
    1.     if request.method == 'GET':
    1.         return render(request,'upload.html')
    1.     elif request.method == 'POST':
    1.         obj = request.FILES.get('fafafa')
    1.         import os
    1.         f = open(os.path.join('upload',obj.name),'wb')
    1.         for line in obj.chunks():
    1.             f.write(line)
    1.         f.close()
    1.         return HttpResponse('test')
    还需要在project目录下建一个upload目录
     
    最后显示如下:
     
     
    还有一个request.body,它是干嘛的额呢?request.POST数据就是从它这里取出来的。
    如果有form表单像后台提交数据,有请求头和请求的内容
    如下:
     
    请求头跟请求体分割是以2个 来实现。
     
    写了一大堆规则,请求头直接用1个 分割,请求头和请求体2个 分割。
    POST是对body 的一个处理。
     
    1个返回字符串,1种返回页面,1种返回跳转
     
    五、模板引擎
    本质上就是帮助咋们做替换,有特殊规则:
     
    特殊规则:
    1、
    { {  k1 }}  获取单值
    2、
    {% if a == 123 %}
    • {% else %}
    {% endif %}
    3、
    {% for item in LIST % }
    • {{ item }}
    • {% endfor %}
    4、
    #索引   :   字典的话就是  字典.k1    列表的话就是 列表.1
    5、字符串全部变成大写
    模板语言也有很多方法
     
     
     
    • 截取前30个单词
    • 写个URL
    1. url(r'^tpl.htm$', views.tpl),
    • 写个views
    1. def tpl(request):
    1.     return render(request,'tpl.html',{'summary':'dfdsfdsffffffffffdddddddddddfdfd'})
     
    • 写个HTML
    1. <body>
    1.     {{ summary }}
    1.     <br/>
    1.     {{ summary|truncatechars:8 }}
    1. </body>
    • 注意上面的取字符的8前面不要有空格,不然会报错
    1. 效果如下:
     
     
    内部提供的功能不够我们使用,我们可以自定义
    需要自定义一些东西,如下:
    1. Invalid filter
    步骤如下:
     
     
     
    1、创建
    2、创建 文件
    写函数,如果普通函数Django不认识,就要装一个装饰器
    名字register不能修改,写成其他的不会认,这样函数就已经生效了。
    1. from django import template
    1. register = template.Library()
     
    1. @register.filter
    1. def ji(value):
    1.     return 'jijiji'
    3、HTML要导入一下
     
     
    4、settings.py里面要注册这个app01,里面的东西才能生效
     
    最终效果
    函数里的value是什么呢?就是前面的summary
    效果如下:
     
    那么:
    冒号后面的值是第2个参数,如下
    1. {{ summary|ji:888 }}
    函数
    结果如下:
     
     
     
    这个就是自定制函数乐,那么有何作用呢?
    让他帮忙生成一个input框,或者1个a标签
     
    以HTML形式显示,就需要做一个处理
    1. from django.utils.safestring import mark_safe
    就会以原生的HTML显示了,不软传的就是一个字符串
    函数形式为
    HTML
    最后形式如下:
     
     
     
    上面叫做页面自定义filter,那有限制吗?
    对于filter,最多只有2个参数,下面要说的就是@register.simple_tag  参数没有限制了
    修改函数
     
    修改HTML
     
    1. {% test 1 2 3 %}
    显示:
     
    simple_tag优势就是参数没限制。
    但是呢。filter有一个优势
    就是在模板语言中支持if条件
    如果做条件用filter,如果仅仅只是返回内容就用simple_tag
     
     
    总结:
     
     
     
    接下来,写一个例子:
    后台管理,模板有重合的地方,页面做一个修改
    这里就涉及到了一个继承的概念。
    新建立一个layout.html文件,让内容能够变动即可。其他的继承即可
     
    1. <!DOCTYPE html>
    1. <html lang="en">
    1. <head>
    1.     <meta charset="UTF-8">
    1.     <title>Title</title>
    1.     <style>
    1.         body{
    1.             margin:0;
    1.         }
    1.         .pg-header{
    1.             height:48px;
    1.            
    1.             color: white;
    1.         }
    1.         .pg-body .menus{
    1.             20%;
    1.             float: left;
    1.            
    1.             height:500px;
    1.         }
    1.         .pg-body .contents{
    1.             80%;
    1.             float: left;
    1.         }
    1.     </style>
    1.      {% block css %}{% endblock %}
    1. </head>
    1. <body>
    1.     <div class="pg-header"></div>
    1.     <div class="pg-body">
    1.         <div class="menus"></div>
    1.         <div class="contents">
    1.             {% block bd %}{% endblock %}
    1.         </div>
    1.     </div>
    1.      {% block js %}{% endblock %}
    1. </body>
    1. </html>
     
    groups.html修改如下。
    第一行就是引入:要继承 谁,然后下面是3个块
    1. {% extends 'layout.html' %}
     
    1. {% block css %}
    1.     <style></style>
     
    1. {% endblock %}
     
    1. {% block bd %}
    1. <h1>组列表</h1>
     
    1. {% endblock %}
     
    1. {% block js %}
    1.     <script></script>
     
    1. {% endblock %}
     
     
    相当于搞了一个父页面,所有子页面继承父页面
    最后页面效果是一样的,
    所以
    一般情况下,预留位置还是预留3块,css    内容  以及js
     
     
    下面做一个分页页码,小组件用上面是不合适的,推荐使用include这个,导入一个小组件
    比如我想导入一个分页
    类似下面,这个
     
    放哪里比较合适呢?
    写一个pager.html
     
     
    然后在引用一下
     
    效果一样的
     
    后台管理,只有登录成功之后才能看,如何实现呢?
     
    http请求是短链接,断开以后在过来,我就不认识了。这样每次去都要登陆一次,这是我们不想要的。
    登录的时候,口袋放一个东西,然后在user函数里面判断,这个东西就是cookie
     
    六、cookie
    每一次来访问,先去浏览器拿东西,拿完东西以后来做检测是否已经登录成功,
    这个cookie是什么呢?
    是用户浏览器上的一个键值对
    这个东西怎么看嗯?
     
    除了做登录,还能做很多事情,比如页面上有个后台管理,可以任意调整。
    还有一个就是页面默认显示10天,左下角有个默认调整100条,都是基于cookie来做的
     
    而cookie就是默认保存在浏览器上的一个键值对。
     
    如果提到cookie的时候,就告诉他。
    它就是一个保存在浏览器的一个键值对,利用它可以实现登录验证以及页面显示条数还有拖动位置等等。
     
    把信息放到cookie保存了,那他多长时间消失呢?
    就是键值对,过了时间消失了,就没有了,所以需要你重新登录。所以对于这个简直对来说,有个特殊性,可以设置超时时间。
    如何设置呢?
    下面就是10s失效
     
    还有一个到哪个时间点失效
     
    这里还有一个path,这个cookie不是瞎写的。因为网站有多个URL,在设置cookie的时候可以设置在哪个URL下生效。比如:不写,就是全局生效,任何页面都能拿到
    默认path就是path='/' ,访问任何都能获取到
    如果我写为path='/index'只有在访问index的时候会带这个值过来,有了路径,还有域名
    domain=' '  访问域名生效。不能瞎写
    httponly=True 只是HTTP传输
    secure=True  就是HTTPS发送
     
    验证如下:
    写views.py
    登录函数
    1. def login(request):
    1.     if  request.method == 'GET':
    1.         return render(request,'login.html')
    1.     elif request.method == 'POST':
    1.         u = request.POST.get('user')
    1.         p = request.POST.get('pwd')
    1.         obj = models.UserInfo.objects.filter(username=u,pwd=p).first()
    1.         #models.UserInfo.objects.filter(username=u,pwd=p).count()
    1.         if obj:
    1.             # 在请求者口袋放东西
    1.             import datetime
    1.             d = datetime.datetime.utcnow()
    1.             m = datetime.timedelta(seconds=10)
    1.             end = d + m
    1.             obj = redirect('/users')
    1.             obj.set_cookie(key='user_name',value=u,max_age=10,expires=end)
    1.             return obj
    1.         else:
    1.             return render(request,'login.html',{'msg':'用户名或密码错误'})
    页面函数
     
    1. def users(request):
     
    1.     #如果去摸口袋,有就登录,没有就重定向到login页面
    1.     v = request.COOKIES.get('user_name')
    1.     if not v:
    1.         return redirect('/login')
    登录的html
    1. <!DOCTYPE html>
    1. <html lang="en">
    1. <head>
    1.     <meta charset="UTF-8">
    1.     <title>Title</title>
    1. </head>
    1. <body>
    1. <form action="/login" method="POST">
    1.     <p><input type="text" name="user"></p>
    1.     <p><input type="password" name="pwd"></p>
    1.     <input type="submit" value="登录"> {{ msg }}
    1. </form>
    1. </body>
    1. </html>
     
    现在有个问题,就是好多页面都要登录成功之后才能访问,那这个users函数就要写多个,怎么办?写个装饰器即可。
    七、session
    两大忌讳:
    敏感信息
    简单值
     
    session是什么东西呢?它也是一个键值对,放在服务器端
     
    首先确保session是放在服务器端的一个键值对。
    这样就设置了session,
    1. request.session['username'] = u
    上面验证也是从session去拿
     
     
     
    这个session浏览器有一份,默认Django数据库也有一份
     
     
     
    具体实现:
    修改函数
    1. def login(request):
    1.     if  request.method == 'GET':
    1.         return render(request,'login.html')
    1.     elif request.method == 'POST':
    1.         u = request.POST.get('user')
    1.         p = request.POST.get('pwd')
    1.         obj = models.UserInfo.objects.filter(username=u,pwd=p).first()
    1.         #models.UserInfo.objects.filter(username=u,pwd=p).count()
    1.         if obj:
    1.             obj = redirect('/users')
    1.             # 在请求者口袋放东西
    1.             request.session['username'] = u
    1.             return obj
    1.         else:
    1.             return render(request,'login.html',{'msg':'用户名或密码错误'})
     
     
    1. def users(request):
     
    1.     #如果去摸口袋,有就登录,没有就重定向到login页面
    1.     v = request.session.get('username')
    1.     if not v:
    1.         return redirect('/login')
     
    区别就是,session保存在服务端,cookie保存在浏览器
     
    推荐登录使用session来做,不要用cookie,但是呢,session依赖于cookie而存在。
     
    Django进阶篇,对于session有个简要说明。
    默认情况下session的时间为二周。
    客户端登录一次,二周内都不用登录,这个可以修改,在settings.py里配置。
     
    这个都是默认的配置,可以自己修改来做到自己想要的效果
    cookie保存在浏览器的键值对
    session保存在服务器端的键值对,不过要基于cookie
     
    把下面这个写成装饰器。
     
    最后实现的效果是一样的
     
     
     
    over!!

     

  • 相关阅读:
    PHPStrom 设置终端字体大小
    PostgreSQL 9 夸库查询
    弹性布局
    sql中的 where 、group by 和 having 用法解析
    数据库面试中常问的几个问题
    SQL中 UNION 和 UNION ALL 操作符小结
    SQL里 inner JOIN、 left (OUTER) JOIN 、right (OUTER) JOIN、 full (OUTER) JOIN 之间的区别
    MYSQL中LIMIT用法
    Java集合框架小结
    jQuery$.each循环遍历详解,各种取值对比,$.each遍历数组、对象、Dom元素、二维数组、双层循坏、类json数据等等
  • 原文地址:https://www.cnblogs.com/jixuege-1/p/6558520.html
Copyright © 2020-2023  润新知