1. 程式人生 > >web後端--Django學習筆記07

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>   &nbsp;
        {% 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後臺管理了

幾個注意點:

  1. 可以在模型類中複寫str(self)方法,後臺顯示每條記錄時會自動呼叫該方法。

  2. 改變模型顯示的樣式:在模型類的class Meta內部類中新增verbose_name_plural。

  3. 後臺中文風格的顯示:在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>   &nbsp;
        {% 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')),