一個初學者的辛酸路程-繼續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’})
流程以下:
請求到來以後到達視圖函數,視圖函數幫助處理返回內容,處理階段,會用到模板引擎渲染,完過後返回給用戶。
1、數據庫操做的增刪改查
實例: 基本curd
一、數據庫設計
id   hostname    ip   port  status
二、在數據庫生成表
三、請求過來,先去處理請求,寫上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裏面生成表
 
這裏須要注意事項:
一、settings.py要註冊app名字
二、若是是連接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文件
修改地方以下:
一、修改全局的URL,如上
  1. url(r'^app01/',include('app01.urls')),
  1. url(r'^app02/',include('app02.urls')),
二、每一個APP裏面新增urls
 
三、修改函數
四、頁面測試訪問
 
 
小結:
之後就把URL作了一個分發
 
 
So
URL這須要記住4點:
一、一個URL對應1個函數,定死的
二、URL存在正則表達式,對應函數,相似1批URL對應函數處理
三、URL後面能夠加別名,經過別名反生出URL
四、對於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種返回跳轉
 
5、模板引擎
本質上就是幫助咋們作替換,有特殊規則:
 
特殊規則:
一、
{ {  k1 }}  獲取單值
二、
{% if a == 123 %}
  • {% else %}
{% endif %}
三、
{% for item in LIST % }
  • {{ item }}
  • {% endfor %}
四、
#索引   :   字典的話就是  字典.k1    列表的話就是 列表.1
五、字符串所有變成大寫
模板語言也有不少方法
 
 
 
  • 截取前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
步驟以下:
 
 
 
一、建立
二、建立 文件
寫函數,若是普通函數Django不認識,就要裝一個裝飾器
名字register不能修改,寫成其餘的不會認,這樣函數就已經生效了。
  1. from django import template
  1. register = template.Library()
 
  1. @register.filter
  1. def ji(value):
  1.     return 'jijiji'
三、HTML要導入一下
 
 
四、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.             width:20%;
  1.             float: left;
  1.            
  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
 
6、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函數就要寫多個,怎麼辦?寫個裝飾器便可。
7、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!!
相關文章
相關標籤/搜索