问题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. 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个\r\n来实现。
 
写了一大堆规则,请求头直接用1个\r\n分割,请求头和请求体2个\r\n分割。
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. color: white;
  1. }
  1. .pg-body .menus{
  1. width:20%;
  1. float: left;
  1. height:500px;
  1. }
  1. .pg-body .contents{
  1. width: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!!

一个初学者的辛酸路程-继续Django的更多相关文章

  1. 一个初学者的辛酸路程-依旧Django

    回顾: 1.Django的请求声明周期?   请求过来,先到URL,URL这里写了一大堆路由关系映射,如果匹配成功,执行对应的函数,或者执行类里面对应的方法,FBV和CBV,本质上返回的内容都是字符串 ...

  2. 一个初学者的辛酸路程-初识Django

    前言: 主要是关于JavaScript的高级部分以及Django 主要内容: 一.jQuery 事件绑定: DOM事件绑定: -直接在标签上绑定 第一种: $('.title').click(func ...

  3. 一个初学者的辛酸路程-基于Django写BBS项目

    前言 基于Django的学习 详情 登录界面 找个模板 http://v3.bootcss.com/examples/signin/ 右键,检查源码     函数 def login(request) ...

  4. 一个初学者的辛酸路程-python操作SQLAlchemy-13

    前言 其实一开始写blog,我是拒绝的,但是,没办法,没有任何理由抗拒.今天呢,要说的就是如何使用Python来操作数据库. SQLAlchemy SQLAlchemy是Python编程语言下的一款O ...

  5. 一个初学者的辛酸路程-FTP-9

    前言 今天,我要描述一个FTP的故事 主要内容 嗯,今天主要以阶梯性的形式来做一个FTP项目. 第一步: 我要实现这么一个功能,一个FTP客户端,1个FTP服务端,2端建立连接以后可以进行通讯. 服务 ...

  6. 一个初学者的辛酸路程-socket编程-8

    前言: 你会发现会网络是多么幸福的事情 主要内容: socket 概念: socket本质上就是2台网络互通的电脑之间,架设一个通道,两台电脑通过这个通道来实现数据的互相传递.我们知道网络通信都是基于 ...

  7. 一个初学者的辛酸路程-Python基础-3

    前言 不要整天沉迷于学习-. 字典 一.我想跟你聊聊字典 1.为何要有字典? 大家有没有想过为什么要有字典?有列表不就可以了吗? 也许大家会这么认为,我给大家举个例子,大家就明白了. 比如说,我通讯录 ...

  8. 一个初学者的辛酸路程-了解Python-2

    前言 blog花了一上午写的,结果笔记本关机了,没有保存,找不到了,找不到了啊,所以说,你看的每一篇blog可能都是我写了2次以上的--.哎!! 代码改变世界,继续......... Python基础 ...

  9. 一个初学者的辛酸路程-初识Python-1

    前言 很喜欢的一句话,与诸位共勉. 人的一切痛苦,本质上都是对自己无能的愤怒----王小波. 初识Python 一.它的爸爸是谁 首先,我们需要认识下面这位人物. 他是Python的创始人,吉多范罗苏 ...

随机推荐

  1. The service command supports only basic LSB actions (start, stop, restart, try-restart, reload,force-reload, status)

    # service iptables save The service command supports only basic LSB actions (start, stop, restart, t ...

  2. php简单开启gzip压缩方法(zlib.output_compression)

    网上的教程基本是你抄我来我抄他,不外乎加头加尾或者自构函数两种写法.实际上每个php页面都要去加代码——当然也可以include引用,不过总显得略微麻烦   一般而言,页面文件开启gzip压缩以后,其 ...

  3. 近期流行的JavaScript框架与主题

    [新年快乐]2017年你应该关注的JavaScript框架与主题 2017-01-01 王下邀月熊 JavaScript JavaScript的繁荣促生了很多优秀的技术.框架与工具库,这空前的繁荣也给 ...

  4. python读取mat文件

    一.mat文件 mat数据格式是Matlab的数据存储的标准格式.在Matlab中主要使用load()函数导入一个mat文件,使用save()函数保存一个mat文件.对于文件 load('data.m ...

  5. miller——rabin

    突然发现自己在线性筛素数中有这个,忘了好久: #include<iostream> #include<cstdio> using namespace std; long lon ...

  6. 解决windows下Composer因php_openssl扩展缺失而安装失败的问题

    Composer( https://getcomposer.org/ )是PHP下的一个依赖管理工具.你可以在你的项目中声明你所需要用到的类库,然后Composer会在项目中为你安装它们.如果你了解N ...

  7. python——文件处理

    1.文件处理 f = open(file="file01.txt", mode="r", encoding="utf-8") #python ...

  8. Login用户登录(Python实现)

    username_fault = "isuperSun" #程序存储用户名和密码 password_fault = " counts = 0 while counts&l ...

  9. 在VSCode中使用码云

    在VSCode中使用码云 一.SSH公钥 使用SSH公钥可以让你在你的电脑和码云通讯的时候使用安全连接(Git的Remote要使用SSH地址) 链接 https://gitee.com/profile ...

  10. Linux文件系统与目录结构

    在Linux系统中,目录被组织成一个:单根倒置树结构,文件系统从根目录开始,用/来表示.文件名称区分大小写( 大小写敏感还需要看具体的文件系统格式 ),以.开头的为隐藏文件,路径用/来进行分割(win ...