web後端--Django學習筆記07
一、第六天作業
1.查詢資料庫完成登入功能和登出功能。 登出session可使用del request.session["key名稱"],也可通過 request.session.set_expiry(value)設定session過期秒數。
2.使用Ajax完成當用戶註冊時,判斷使用者名稱是否已經存在,如果 在資料庫中已經有該使用者,則給使用者在前臺提示“該使用者名稱已存在,請 重新輸入註冊使用者名稱”。
1.1程式碼演示
1、models
from django.db import models class RegUser(models.Model): username = models.CharField(max_length=20) password = models.CharField(max_length=20) def __str__(self): return self.username class Meta: db_table = 'regusers' verbose_name = "註冊使用者模型" verbose_name_plural = verbose_name
2、views
from django.core.paginator import Paginator, Page from django.http import HttpResponse from django.shortcuts import render, redirect from django.urls import reverse from homework.models import RegUser def go_reg(request): return render(request,'register.html') def go_login(request): return render(request,'login.html') def go_success(request): return render(request,'success.html') def wrong_login(request,msg): return render(request, 'login.html',locals()) def login(request): login_name = request.POST["login_name"] login_pwd = request.POST["login_pwd"] if login_name == "tom" and login_pwd == "123456": request.session["loginname"] = login_name # 使用者名稱密碼都正確,設定session屬性 return redirect(reverse('home:gosuccess')) else: return redirect(reverse('home:wronglogin',args=('使用者名稱或密碼錯誤,請重新登入',))) def logout(request): # 登出 del request.session["loginname"] # 刪除session的loginname屬性 return redirect(reverse("home:gologin")) def check_regname(request): regname = request.GET["regname"] results = RegUser.objects.filter(username=regname) if results: return HttpResponse("sorry,該使用者名稱已被註冊!!!") else: return HttpResponse("恭喜,可以註冊~")
3、templates
<!login.html> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>登入頁面</title> </head> <body> <h3 style="color:red"> {{ msg }}</h3> <form action="{% url 'home:login' %}" method="post"> {% csrf_token %} 使用者名稱:<input type="text" name="login_name"/> <br/> 密碼:<input type="password" name="login_pwd"/> <br/> <input type="submit" value="登入"/> </form> </body> </html>
<!success.html> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>成功頁面</title> </head> <body> {% if request.session.loginname %} <h3> 歡迎<span style="color:blue"> {{ request.session.loginname }} 訪問本網站 </span> </h3> <a href="{% url 'home:logout' %}">登出</a> {% else %} <h3>您還未登入,請先<a href="{% url 'home:gologin' %}"> 登入 </a></h3> {% endif %} </body> </html>
<!register.html> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>註冊頁面</title> <script type="text/javascript"> //AJAX function getXHR(){ var xhr=null; if(window.XMLHttpRequest){ xhr=new XMLHttpRequest() }else{ xhr=new ActiveXObject('Microsoft.XMLHTTP') } return xhr; } function check_regname(){ xhr = getXHR(); // 獲取Ajax物件 regname = document.getElementById("regname").value; // 獲取輸入的註冊名 xhr.open('get','/homework/checkname/?regname='+regname,true); xhr.onreadystatechange=function(){ if(xhr.readyState==4){ if(xhr.status==200){ var msg=xhr.responseText; // 接收服務端傳送的文字 document.getElementById("msg").innerHTML=msg; } } } xhr.send(null); } </script> </head> <body> <form action="" method="post"> {% csrf_token %} 註冊使用者名稱:<input type="text" name="reg_name" id="regname" onblur="check_regname()"/> <span id="msg" style="color:red"></span> <br/> 註冊密碼:<input type="password" name="reg_pwd"/> <br/> <input type="submit" value="註冊"/> </form> </body> </html>
4、urls
#子路由 from django.urls import path from homework.views import * app_name = "homework" urlpatterns = [ path('gologin/',go_login,name="gologin"), path('wronglogin/<msg>/',wrong_login,name='wronglogin'), path('gosuccess/',go_success,name="gosuccess"), path('login/',login,name="login"), path('logout/',logout,name="logout"), path('goreg/',go_reg), path('checkname/',check_regname,name="check"), ] #總路由 path('homework/',include('homework.urls',namespace='home')),
二:Django載入靜態資源
Django通過“靜態資源探測器”探測的目錄,在這些目錄下尋找要載入的靜態資源。 “靜態資源探測器”首先從STATICFILES_DIRS變數(在settings.py中配置)指定的 目錄中尋找靜態資源;然後去找應用app中的static目錄,在該目錄中繼續尋找靜態資源。
1、幾個重要配置:
STATIC_URL (必須):指定了訪問靜態資源的初始URL,當該URL為該變數指定的值時, “靜態資源探測器”開始探測靜態資源所在的目錄。
STATICFILES_DIRS: 指定了“靜態資源探測器”的探測目錄列表
STATIC_ROOT : 指定了將所有應用的靜態資源收集到的目錄。 使用python manage.py collectstatic
STATIC_URL = '/abc/' #/abc/可隨意修改 STATICFILES_DIRS = [ os.path.join(BASE_DIR,'static'), ] STATIC_ROOT = os.path.join(BASE_DIR,'collectstatic') #然後在終端輸入 python manage.py collectstatic
2、模板中如何載入靜態資源?
1.載入static標籤 {% load static %}2.使用static標籤訪問靜態資源 {% static '靜態資源路徑' %}
3、程式碼演示
1、models
from django.db import models class Student(models.Model): name = models.CharField(max_length=20,verbose_name="學生姓名") age = models.IntegerField(verbose_name="學生年齡") sex = models.CharField(max_length=10,verbose_name="性別") score = models.FloatField(verbose_name="成績") def __str__(self): return self.name class Meta: db_table = 'students' verbose_name_plural = "學生模型"
2、views
from django.core.paginator import Paginator from django.shortcuts import render from myapp.models import Student def go_main(request): return render(request,'main.html') # 根據頁碼獲取對應頁碼的資料 def get_students_by_page(request,page_number=1): students = Student.objects.all() paginator = Paginator(students,3) # 例項化分頁器物件,第一個引數是資料來源,第二個引數是每頁顯示的條數 page = paginator.page(page_number) # 返回page_number頁的資料,以Page物件的方式封裝該頁資料 return render(request,'student/all_students.html',locals())
3、templates
<!DOCTYPE html> {% load static %} <!載入靜態資源> <html lang="en"> <head> <meta charset="UTF-8"> <title>主頁面</title> </head> <body> <h3>歡迎訪問主頁面</h3> <img src="{% static 'images/monkey.jpg' %}"/> <!訪問靜態資源> </body> </html>
<!all_students.html> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>分頁顯示所有學生</title> </head> <body> <table border="1" align="center"> <thead> <tr> <th>學號</th> <th>姓名</th> <th>年齡</th> <th>性別</th> <th>成績</th> </tr> </thead> <tbody> {% for student in page %} <tr> <td> {{ student.id }} </td> <td> {{ student.name }} </td> <td> {{ student.age }} </td> <td> {{ student.sex }} </td> <td> {{ student.score }} </td> </tr> {% endfor %} </tbody> </table> <center> <a href="{% url 'myapp:students' 1 %}">首頁</a> {% if page.has_previous %} <a href="{% url 'myapp:students' page.previous_page_number %}">上一頁</a> {% else %} <a href="javascript:alert('已經是第一頁啦!')">上一頁</a> {% endif %} {% if page.has_next %} <a href="{% url 'myapp:students' page.next_page_number %}">下一頁</a> {% else %} <a href="javascript:alert('已經是最後一頁了!')">下一頁</a> {% endif %} <a href="{% url 'myapp:students' paginator.num_pages %}">末頁</a> <hr/> {% for page_number in paginator.page_range %} <a href="{% url 'myapp:students' page_number %}"> {{ page_number }} </a> {% endfor %} </center> </body> </html>
4、urls
#子路由 from django.urls import path from myapp.views import * app_name = 'myapp' urlpatterns = [ path('gomain/',go_main), path('students/<page_number>/',get_students_by_page,name="students"), ] #總路由 path('myapp/',include('myapp.urls',namespace='myapp')),
三:admin後臺管理
Django提供了一個功能強大的後臺管理系統,進入admin系統的路徑: http://ip地址:埠號/admin
http://localhost:8000/admin
建立超級使用者:python manage.py createsuperuser在應用的admin.py中註冊模型: admin.site.register([模型類名稱1,模型類名稱2...]) 注意:註冊模型後,則該模型就可以被admin後臺管理了
幾個注意點:
-
可以在模型類中複寫str(self)方法,後臺顯示每條記錄時會自動呼叫該方法。
-
改變模型顯示的樣式:在模型類的class Meta內部類中新增verbose_name_plural。
-
後臺中文風格的顯示:在settings.py中將LANGUAGE_CODE的值設定為:'zh-Hans'。
#models。py class Meta: db_table = 'regusers' verbose_name = "註冊使用者模型" verbose_name_plural = verbose_name #去掉複數
#settings.py LANGUAGE_CODE = 'zh-Hans'
四:Django分頁器
1.Paginator分頁器物件
例項化分頁器物件: paginator = Paginator(資料來源,每頁最多顯示的條數)
分頁器物件的常用方法: page(頁碼引數) # 該方法返回一個Page物件,該Page物件封裝了某一頁的資料
分頁器物件的常用屬性: num_pages # 返回總的頁數 page_range # 返回從1開始的頁碼範圍
2、Page物件(可迭代物件)
常用方法:has_previous() # 當前頁是否有前一頁previous_page_number() # 前一頁的頁碼has_next() # 當前頁是否有下一頁next_page_number() # 下一頁的頁碼
3、程式碼演示
1、models
from django.db import models class Student(models.Model): name = models.CharField(max_length=20,verbose_name="學生姓名")#重新命名後臺管理名稱 age = models.IntegerField(verbose_name="學生年齡") sex = models.CharField(max_length=10,verbose_name="性別") score = models.FloatField(verbose_name="成績") def __str__(self): return self.name class Meta: db_table = 'students' verbose_name_plural = "學生模型"
2、views
from django.core.paginator import Paginator from django.shortcuts import render from myapp.models import Student def go_main(request): return render(request,'main.html') # 根據頁碼獲取對應頁碼的資料 def get_students_by_page(request,page_number=1): students = Student.objects.all() paginator = Paginator(students,3) # 例項化分頁器物件,第一個引數是資料來源,第二個引數是每頁顯示的條數 page = paginator.page(page_number) # 返回page_number頁的資料,以Page物件的方式封裝該頁資料 return render(request,'student/all_students.html',locals())
3、admin
from django.contrib import admin from myapp.models import Student admin.site.register([Student,])
4、templates
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>分頁顯示所有學生</title> </head> <body> <table border="1" align="center"> <thead> <tr> <th>學號</th> <th>姓名</th> <th>年齡</th> <th>性別</th> <th>成績</th> </tr> </thead> <tbody> {% for student in page %} <tr> <td> {{ student.id }} </td> <td> {{ student.name }} </td> <td> {{ student.age }} </td> <td> {{ student.sex }} </td> <td> {{ student.score }} </td> </tr> {% endfor %} </tbody> </table> <center> <a href="{% url 'myapp:students' 1 %}">首頁</a> {% if page.has_previous %} <a href="{% url 'myapp:students' page.previous_page_number %}">上一頁</a> {% else %} <a href="javascript:alert('已經是第一頁啦!')">上一頁</a> {% endif %} {% if page.has_next %} <a href="{% url 'myapp:students' page.next_page_number %}">下一頁</a> {% else %} <a href="javascript:alert('已經是最後一頁了!')">下一頁</a> {% endif %} <a href="{% url 'myapp:students' paginator.num_pages %}">末頁</a> <hr/> {% for page_number in paginator.page_range %} <a href="{% url 'myapp:students' page_number %}"> {{ page_number }} </a> {% endfor %} </center> </html>
5、urls
#子路由 from django.urls import path from myapp.views import * app_name = 'myapp' urlpatterns = [ path('gomain/',go_main), path('students/<page_number>/',get_students_by_page,name="students"), ] #總路由 path('myapp/',include('myapp.urls',namespace='myapp')),
五:Django內建認證系統
Django內建認證系統的使用者類是: from django.contrib.auth.models import User該User模型類對應於auth_user表
1、插入auth_user表中的一條記錄
User.objects.create_user(username=regname,password=regpwd) # 使用create_user()建立使用者,並對密碼加密
2、驗證使用者名稱和密碼是否正確
user = authenticate(username=login_name,password=login_pwd) # 驗證使用者名稱和密碼 如果使用者名稱和密碼正確,則返回一個User物件;否則返回None
3、登入成功後,將使用者與Session關聯
login(request,user) # 將使用者標識儲存到Session中注意:login函式是系統內建的
4、進行登入驗證
在模板中使用{% if request.user.is_authenticated %} 登入驗證成功後,顯示此處{% endif %}
5、登出
logout(request) # 該函式會將後臺的Session記錄刪除
3、程式碼演示
1、views
from django.contrib.auth import authenticate, login, logout from django.contrib.auth.models import User from django.shortcuts import render, redirect from django.urls import reverse def go_register(request): return render(request,'authapp/register.html') def go_login(request): return render(request, 'authapp/login.html') def wrong_login(request,msg): return render(request, 'authapp/login.html',locals()) def go_success(request): return render(request,'authapp/success.html') # 註冊 def register_user(request): regname = request.POST["regname"] regpwd = request.POST["regpwd"] User.objects.create_user(username=regname,password=regpwd) # 使用create_user()建立使用者,並對密碼加密 return redirect(reverse("authapp:gologin")) # 重定向 # 登入 def user_login(request): login_name = request.POST["login_name"] login_pwd = request.POST["login_pwd"] user = authenticate(username=login_name,password=login_pwd) # 驗證使用者名稱和密碼 print("查詢到的使用者是:",user) if user: # 如果驗證成功,則返回User物件 print("user的型別是:",type(user)) login(request,user) # 將使用者標識儲存到Session中 return redirect(reverse("authapp:success")) else: # 如果驗證失敗,則返回None return redirect(reverse("authapp:wrong",args=("哎呀,輸錯了,驗證失敗",))) def user_logout(request): logout(request) # 登出 return redirect(reverse("authapp:gologin")) # 重定向
2、templates
<!register.hteml> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>註冊</title> </head> <body> <form action="{% url 'authapp:reg' %}" method="post"> {% csrf_token %} 請輸入註冊使用者名稱:<input type="text" name="regname"/> <br/> 請輸入註冊密碼:<input type="password" name="regpwd"/> <br/> <input type="submit" value="註冊"/> </form> </body> </html>
<!login.html> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>登入頁面</title> </head> <body> <h3 style="color:red"> {{ msg }} </h3> <form action="{% url 'authapp:login' %}" method="post"> {% csrf_token %} 請輸入登入使用者名稱:<input type="text" name="login_name"/> <br/> 請輸入登入密碼:<input type="password" name="login_pwd"/> <br/> <input type="submit" value="登入"/> </form> </body> </html>
<!success.html> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>成功頁面</title> </head> <body> {% if request.user.is_authenticated %} <h3>Welcome, <span style="color:green"> {{ request.user.username }} ,Nice to meet you~~~</span> </h3> <a href="{% url 'authapp:logout' %}">登出</a> {% else %} <h3>還是先<a href="{% url 'authapp:gologin' %}"> 登入 </a>吧</h3> {% endif %} </body> </html>
3、urls
#子路由 from django.urls import path from authapp.views import * app_name = 'authapp' urlpatterns = [ path('goreg/',go_register), path('gologin/',go_login,name="gologin"), path('wronglogin/<msg>/',wrong_login,name="wrong"), path('gosuccess/',go_success,name="success"), path('register/',register_user,name="reg"), path('login/',user_login,name="login"), path('logout/',user_logout,name="logout"), ] #總路由 path('authapp/',include('authapp.urls',namespace='authapp')),