Django 小實例S1 簡易學生選課管理系統 第6節——實現登錄邏輯
點擊查看教程總目錄
作者自我介紹:b站小UP主,時常直播編程+紅警三,python1對1輔導老師。
1 業務邏輯
本教程第四節里面實現了登錄頁面和一個空的登錄邏輯。
第六節這里就把登錄邏輯補全。
登錄的業務邏輯是:
- 檢查是否注冊
- 未注冊,則提示賬號不存在
- 注冊但密碼不匹配,提示密碼不正確
- 注冊且信息匹配,成功登錄,跳轉到個人主頁,同時通過cookie保存登錄信息。
對於教務管理系統,個人主頁應該是其課程主頁,所以本部分還需要添加課程主頁,這里先只實現一個空的展示其個人信息的課程主頁。
2 修改登錄視圖
修改user/views.py
中的login
方法如下:
def login(request, kind):
if kind not in ["teacher", "student"]:
return HttpResponse(INVALID_KIND)
if request.method == 'POST':
if kind == "teacher":
form = TeaLoginForm(data=request.POST)
else:
form = StuLoginForm(data=request.POST)
if form.is_valid():
uid = form.cleaned_data["uid"]
if len(uid) != 10:
form.add_error("uid", "賬號長度必須為10")
else:
if kind == "teacher":
department_no = uid[:3]
number = uid[3:]
object_set = Teacher.objects.filter(department_no=department_no, number=number)
else:
grade = uid[:4]
number = uid[4:]
object_set = Student.objects.filter(grade=grade, number=number)
if object_set.count() == 0:
form.add_error("uid", "該賬號不存在.")
else:
user = object_set[0]
if form.cleaned_data["password"] != user.password:
form.add_error("password", "密碼不正確.")
else:
request.session['kind'] = kind
request.session['user'] = uid
request.session['id'] = user.id
return redirect("course", kind=kind)
return render(request, 'user/login_detail.html', {'form': form, 'kind': kind})
else:
context = {'kind': kind}
if request.GET.get('uid'):
uid = request.GET.get('uid')
context['uid'] = uid
if kind == "teacher":
form = TeaLoginForm({"uid": uid, 'password': '12345678'})
else:
form = StuLoginForm({"uid": uid, 'password': '12345678'})
else:
if kind == "teacher":
form = TeaLoginForm()
else:
form = StuLoginForm()
context['form'] = form
if request.GET.get('from_url'):
context['from_url'] = request.GET.get('from_url')
return render(request, 'user/login_detail.html', context)
登錄后會在cookie中存儲以下信息:
kind
: 用戶類型,學生或老師user
: 用戶學號或教師編號
3 添加簡單主頁
目前雖然是個人主頁,但是后面將會是課程主頁,老師的和學生的必然是不同的。
所以我們現在也先提前規划好,將主頁分為學生的和老師的來處理。
course/views.py
代碼如下
from django.http.response import HttpResponse
from django.shortcuts import render, reverse, redirect
from user.models import Student, Teacher
from constants import INVALID_KIND
def get_user(request, kind):
"""
:param request:
:param kind: teacher or student
:return: return Teacher instance or Student instance
"""
if request.session.get('kind', '') != kind or kind not in ["student", "teacher"]:
return None
if len(request.session.get('user', '')) != 10:
return None
uid = request.session.get('user')
if kind == "student":
# 找到對應學生
grade = uid[:4]
number = uid[4:]
student_set = Student.objects.filter(grade=grade, number=number)
if student_set.count() == 0:
return None
return student_set[0]
else:
# 找到對應老師
department_no = uid[:3]
number = uid[3:]
teacher_set = Teacher.objects.filter(department_no=department_no, number=number)
if teacher_set.count() == 0:
return None
return teacher_set[0]
# Create your views here.
def home(request, kind):
if kind == "teacher":
return teacher_home(request)
elif kind == "student":
return student_home(request)
return HttpResponse(INVALID_KIND)
def teacher_home(request):
kind = "teacher"
user = get_user(request, kind)
if not user:
return redirect('login', kind=kind)
info = {
"name": user.name,
"kind": kind
}
context = {
"info": info
}
return render(request, 'course/nav.html', context)
def student_home(request):
kind = "student"
user = get_user(request, kind)
if not user:
return redirect('login', kind = kind)
info = {
"name": user.name,
"kind": kind
}
context = {
"info": info
}
return render(request, 'course/nav.html', context)
注意,跳轉到一個帶參數的url,有兩種寫法
return redirect(reverse("login", kwargs={"kind": kind}))
return redirect('login', kind = kind)
這兩種寫法返回效果一樣
添加模板文件templates/course/nav.html
<!DOCTYPE html>
<html lang="en">
{% load static %}
<head>
<meta charset="UTF-8">
<title>
{% block title %}{% endblock %}
</title>
</head>
<body>
<div class="nav">
<div class="nav-title">
<a href="{% url 'course' kind=info.kind %}">
<p class="main-title">學生選課管理系統</p>
<p class="sub-title">
{% if info.kind == "teacher" %}
教師端
{% elif info.kind == "student" %}
學生端
{% endif %}</p>
</a>
</div>
<div class="name-logo">
<div class="user-name">
{{ info.name }}
</div>
</div>
</div>
<div class="main-content">
{% block content %}{% endblock %}
</div>
</body>
</html>
然后添加course/urls.py
如下
from django.urls import path
from course.views import *
urlpatterns = [
path('<slug:kind>/', home, name="course"),
]
同時還要去改下主url,即在SSCMS/urls.py
的urlpatterns
中添加
path('course/', include("course.urls")),
此時運行軟件,登錄賬號后(這里又注冊了一個叫李大爽的用戶),
結果如圖
4 實現退出登錄
退出登錄的視圖方法如下(在user/views.py
中添加)
def logout(request):
if request.session.get("kind", ""):
del request.session["kind"]
if request.session.get("user", ""):
del request.session["user"]
if request.session.get("id", ""):
del request.session["id"]
return redirect(reverse("login"))
添加對應路由(在user/urls.py
中的urlpatterns
的添加)
path('logout/', views.logout, name="logout")
在修改下登錄后的主頁視圖(即templates/course/nav.html
)
在其中的第24行處(即<div class="name-logo">
的之前)添加
<div class="log-out">
<a href="{% url "logout" %}">退出</a>
</div>
此時登錄后,主頁面如下圖
點擊退出按鈕,就可以退出登錄,返回登錄主頁面。
5 簡化登錄主頁url
每次要打開登錄主頁,都需要在瀏覽器中輸入http://127.0.0.1:8000/user/login
運行django后,控制台只自動給出http://127.0.0.1:8000
。
所以這里修改下urlpattern,能夠訪問http://127.0.0.1:8000
即得到登錄主頁
修改后的SSCMS/urls.py
如下
from django.urls import path, include
from user.views import home
urlpatterns = [
path('', home, name="login"),
path('user/', include("user.urls")),
path('course/', include("course.urls")),
]