Django組件
Django的分頁器(paginator)
demo
視圖
from django.shortcuts import render,HttpResponse # Create your views here. from app01.models import * from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger def index(request): ‘‘‘ 批量導入數據: Booklist=[] for i in range(100): Booklist.append(Book(title="book"+str(i),price=30+i*i)) Book.objects.bulk_create(Booklist)view‘‘‘ ‘‘‘ 分頁器的使用: book_list=Book.objects.all() paginator = Paginator(book_list, 10) print("count:",paginator.count) #數據總數 print("num_pages",paginator.num_pages) #總頁數 print("page_range",paginator.page_range) #頁碼的列表 page1=paginator.page(1) #第1頁的page對象 for i in page1: #遍歷第1頁的所有數據對象 print(i) print(page1.object_list) #第1頁的所有數據 page2=paginator.page(2) print(page2.has_next()) #是否有下一頁 print(page2.next_page_number()) #下一頁的頁碼 print(page2.has_previous()) #是否有上一頁 print(page2.previous_page_number()) #上一頁的頁碼 # 拋錯 #page=paginator.page(12) # error:EmptyPage #page=paginator.page("z") # error:PageNotAnInteger‘‘‘ book_list=Book.objects.all() paginator = Paginator(book_list, 10) page = request.GET.get(‘page‘,1) currentPage=int(page) try: print(page) book_list = paginator.page(page) except PageNotAnInteger: book_list = paginator.page(1)except EmptyPage: book_list = paginator.page(paginator.num_pages) return render(request,"index.html",{"book_list":book_list,"paginator":paginator,"currentPage":currentPage})
模板
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> </head> <body> <div class="container"> <h4>分頁器</h4> <ul> {% for book in book_list %} <li>{{ book.title }} -----{{ book.price }}</li> {% endfor %} </ul> <ul class="pagination" id="pager"> {% if book_list.has_previous %} <li class="previous"><a href="/index/?page={{ book_list.previous_page_number }}">上一頁</a></li> {% else %} <li class="previous disabled"><a href="#">上一頁</a></li> {% endif %} {% for num in paginator.page_range %} {% if num == currentPage %} <li class="item active"><a href="/index/?page={{ num }}">{{ num }}</a></li> {% else %} <li class="item"><a href="/index/?page={{ num }}">{{ num }}</a></li> {% endif %} {% endfor %} {% if book_list.has_next %} <li class="next"><a href="/index/?page={{ book_list.next_page_number }}">下一頁</a></li> {% else %} <li class="next disabled"><a href="#">下一頁</a></li> {% endif %} </ul> </div> </body> </html>html
進階限制所顯示的分頁數量
1 def index(request): 2 3 4 book_list=Book.objects.all() 5 6 paginator = Paginator(book_list, 15) 7 page = request.GET.get(‘page‘,1) 8 currentPage=int(page) 9 10 # 如果頁數十分多時,換另外一種顯示方式 11 if paginator.num_pages>11: 12 13 if currentPage-5<1: 14 pageRange=range(1,11) 15 elif currentPage+5>paginator.num_pages: 16 pageRange=range(currentPage-5,paginator.num_pages+1) 17 18 else: 19 pageRange=range(currentPage-5,currentPage+5) 20 21 else: 22 pageRange=paginator.page_range 23 24 25 try: 26 print(page) 27 book_list = paginator.page(page) 28 except PageNotAnInteger: 29 book_list = paginator.page(1) 30 except EmptyPage: 31 book_list = paginator.page(paginator.num_pages) 32 33 34 return render(request,"index.html",locals())more
Cookie與Session
我們知道HTTP協議是無狀態協議,也就是說每個請求都是獨立的!無法記錄前一次請求的狀態。但HTTP協議中可以使用Cookie來完成會話跟蹤!在Web開發中,使用session來完成會話跟蹤,session底層依賴Cookie技術。
cookie
其實Cookie是key-value結構,類似於一個python中的字典。隨著服務器端的響應發送給客戶端瀏覽器。然後客戶端瀏覽器會把Cookie保存起來,當下一次再訪問服務器時把Cookie再發送給服務器。 Cookie是由服務器創建,然後通過響應發送給客戶端的一個鍵值對。客戶端會保存Cookie,並會標註出Cookie的來源(哪個服務器的Cookie)。當客戶端向服務器發出請求時會把所有這個服務器Cookie包含在請求中發送給服務器,這樣服務器就可以識別客戶端了!
- Cookie大小上限為4KB;
- 一個服務器最多在客戶端瀏覽器上保存20個Cookie;
- 一個瀏覽器最多保存300個Cookie;
cookie與HTTP頭
Cookie是通過HTTP請求和響應頭在客戶端和服務器端傳遞的:
- Cookie:請求頭,客戶端發送給服務器端;
- 格式:Cookie: a=A; b=B; c=C。即多個Cookie用分號離開; ? Set-Cookie:響應頭,服務器端發送給客戶端;
- 一個Cookie對象一個Set-Cookie: Set-Cookie: a=A Set-Cookie: b=B Set-Cookie: c=C
cookie的覆蓋
如果服務器端發送重復的Cookie那麽會覆蓋原有的Cookie,例如客戶端的第一個請求服務器端發送的Cookie是:Set-Cookie: a=A;第二請求服務器端發送的是:Set-Cookie: a=AA,那麽客戶端只留下一個Cookie,即:a=AA。
django中的cookie語法
設置cookie:
rep = HttpResponse(...) 或 rep = render(request, ...) 或 rep = redirect() rep.set_cookie(key,value,...) rep.set_signed_cookie(key,value,salt=‘加密鹽‘,...)
獲取cookie:
request.COOKIES
刪除cookie:
response.delete_cookie("cookie_key",path="/",domain=name)
session
Session是服務器端技術,利用這個技術,服務器在運行時可以 為每一個用戶的瀏覽器創建一個其獨享的session對象,由於 session為用戶瀏覽器獨享,所以用戶在訪問服務器的web資源時 ,可以把各自的數據放在各自的session中,當用戶再去訪問該服務器中的其它web資源時,其它web資源再從用戶各自的session中 取出數據為用戶服務。
django中的session語法
1、設置Sessions值 request.session[‘session_name‘] ="admin" 2、獲取Sessions值 session_name = request.session["session_name"] 3、刪除Sessions值 del request.session["session_name"] 4、flush() 刪除當前的會話數據並刪除會話的Cookie。 這用於確保前面的會話數據不可以再次被用戶的瀏覽器訪問
5、get(key, default=None) fav_color = request.session.get(‘fav_color‘, ‘red‘) 6、pop(key) fav_color = request.session.pop(‘fav_color‘) 7、keys() 8、items() 9、setdefault() 用戶session的隨機字符串 request.session.session_key # 將所有Session失效日期小於當前日期的數據刪除 request.session.clear_expired() # 檢查 用戶session的隨機字符串 在數據庫中是否 request.session.exists("session_key") # 刪除當前用戶的所有Session數據 request.session.delete("session_key") request.session.set_expiry(value) * 如果value是個整數,session會在些秒數後失效。 * 如果value是個datatime或timedelta,session就會在這個時間後失效。 * 如果value是0,用戶關閉瀏覽器session就會失效。 * 如果value是None,session會依賴全局session失效策略。 補充語法more
session配置
Django默認支持Session,並且默認是將Session數據存儲在數據庫中,即:django_session 表中。 a. 配置 settings.py SESSION_ENGINE = ‘django.contrib.sessions.backends.db‘ # 引擎(默認) SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在瀏覽器上時的key,即:sessionid=隨機字符串(默認) SESSION_COOKIE_PATH = "/" # Session的cookie保存的路徑(默認) SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名(默認) SESSION_COOKIE_SECURE = False # 是否Https傳輸cookie(默認) SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http傳輸(默認) SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周)(默認) SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否關閉瀏覽器使得Session過期(默認) SESSION_SAVE_EVERY_REQUEST = False # 是否每次請求都保存Session,默認修改之後才保存(默認)
用戶認證組件auth
auth模塊
from django.contrib import auth
django.contrib.auth中提供了許多方法,這裏主要介紹其中的三個:
authenticate()
提供了用戶認證,即驗證用戶名以及密碼是否正確,一般需要username password兩個關鍵字參數
如果認證信息有效,會返回一個 User 對象。authenticate()會在User 對象上設置一個屬性標識那種認證後端認證了該用戶,且該信息在後面的登錄過程中是需要的。當我們試圖登陸一個從數據庫中直接取出來不經過authenticate()的User對象會報錯的!!
user = authenticate(username=‘someone‘,password=‘somepassword‘)
login(HttpRequest,user)
該函數接受一個HttpRequest對象,以及一個認證了的User對象 此函數使用django的session框架給某個已認證的用戶附加上session id等信息。
from django.contrib.auth import authenticate, login def my_view(request): username = request.POST[‘username‘] password = request.POST[‘password‘] user = authenticate(username=username, password=password) if user is not None: login(request, user) # Redirect to a success page. ... else: # Return an ‘invalid login‘ error message. ...
logout(request) 註銷用戶
from django.contrib.auth import logout def logout_view(request): logout(request) # Redirect to a success page.
該函數接受一個HttpRequest對象,無返回值。當調用該函數時,當前請求的session信息會全部清除。該用戶即使沒有登錄,使用該函數也不會報錯。
User對象
User 對象屬性:username, password(必填項)password用哈希算法保存到數據庫
user對象的is_authenticated()
如果是真正的user 對象,返回值恒為True.用於檢查用戶是否已經通過了驗證.
通過認證並不意味著用戶擁有任何權限,甚至也不檢查該用戶是否處於激活狀態,這只是表明用戶成功的通過了驗證,這個方法很重要,在後臺用request.
user.is_authenticated()判斷用戶是否已經登錄,如果true則可以向前臺展示request.user.name
要求:
1 用戶登陸後才能訪問某些頁面,
2 如果用戶沒有登錄就訪問該頁面的話直接跳到登錄頁面
3 用戶在跳轉的登陸界面中完成登陸後,自動訪問跳轉到之前訪問的地址
方法1:
def my_view(request): if not request.user.is_authenticated(): return redirect(‘%s?next=%s‘ % (settings.LOGIN_URL, request.path))
方法2:
django已經為我們設計好了一個用於此種情況的裝飾器:login_requierd()
from django.contrib.auth.decorators import login_required @login_required def my_view(request): ‘‘‘
若用戶沒有登錄,則會跳轉到django默認的 登錄URL ‘/accounts/login/ ‘ (這個值可以在settings文件中通過LOGIN_URL進行修改)。並傳遞 當前訪問url的絕對路徑 (登陸成功後,會重定向到該路徑)。
2.2創建用戶
使用 create_user 輔助函數創建用戶:
from django.contrib.auth.models import User user = User.objects.create_user(username=‘‘,password=‘‘,email=‘‘)
2.3 check_password(password)
用戶需要修改密碼的時候 首先要讓他輸入原來的密碼 ,如果給定的字符串通過了密碼檢查,返回 True
2.4 修改密碼
使用 set_password() 來修改密碼
user = User.objects.get(username=‘‘) user.set_password(password=‘‘) user.save
def sign_up(request): state = None if request.method == ‘POST‘: password = request.POST.get(‘password‘, ‘‘) repeat_password = request.POST.get(‘repeat_password‘, ‘‘) email=request.POST.get(‘email‘, ‘‘) username = request.POST.get(‘username‘, ‘‘) if User.objects.filter(username=username): state = ‘user_exist‘ else: new_user = User.objects.create_user(username=username, password=password,email=email) new_user.save() return redirect(‘/book/‘) content = { ‘state‘: state, ‘user‘: None, } return render(request, ‘sign_up.html‘, content) 註冊代碼register
@login_required def set_password(request): user = request.user state = None if request.method == ‘POST‘: old_password = request.POST.get(‘old_password‘, ‘‘) new_password = request.POST.get(‘new_password‘, ‘‘) repeat_password = request.POST.get(‘repeat_password‘, ‘‘) if user.check_password(old_password): if not new_password: state = ‘empty‘ elif new_password != repeat_password: state = ‘repeat_error‘ else: user.set_password(new_password) user.save() return redirect("/log_in/") else: state = ‘password_error‘ content = { ‘user‘: user, ‘state‘: state, } return render(request, ‘set_password.html‘, content) 修改密碼的代碼password
Django組件