1. 创建user模型,修改model.py:
from hashlib import sha1
from django.db import models
from django.db.models import PROTECT
# 高类聚、低耦合
# 面向对象七个设计原则
# 单一职责原则 / 开闭原则 / 依赖倒转原则 / 里氏替换原则 / 接口隔离原则 / 合成聚合复用原则 / 迪米特法则
# 1995年 - GoF - 23个设计模式
# 创建型模式中的原型模式
proto = sha1()
class User(models.Model):
no = models.AutoField(primary_key=True, db_column='uno', verbose_name='用户编号')
username = models.CharField(max_length=20, unique=True, verbose_name='用户名')
password = models.CharField(max_length=40, verbose_name='口令')
email = models.CharField(max_length=255, null=True, verbose_name='邮箱')
class Meta:
db_table = 'tb_user'
verbose_name = '用户'
verbose_name_plural = '用户'
def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
hasher = proto.copy() # 更有效率的做法,复制对象比创建对象更快
hasher.update(self.password.encode('utf-8'))
self.password = hasher.hexdigest()
super().save(force_insert, force_update, using, update_fields)
注意导入python自带的hashlib中的sha1,创建对象proto之后,针对用户密码password进行复制对象,比每一次生成密码安全码之后创建对象更有效率。
2. 创建两个模板:
login
用户登陆
用户登陆
{{ hint }}
注册新用户
注意hint的提示放置,主要呈现在页面刷新后被调用时;以及csrf_token,只要有用户密码等,就必须有这个设置。
register
用户注册
用户注册
注意type类型的修改,最后a标签路径的设置;也可自行加入css进行页面渲染美化。设置两行密码输入验证一致性。以及登陆和注册页面相互跳转的逻辑。
3. 视图文件的修改,views.py:
import json
from django.http import HttpResponse
from django.shortcuts import render, redirect
from demo1.models import Subject, Teacher, User, proto
def login(request):
if request.method == 'GET':
return render(request, 'demo/login.html')
else:
username = request.POST['username']
try:
user = User.objects.get(username__exact=username)
password = request.POST['password']
hasher = proto.copy()
hasher.update(password.encode('utf-8'))
if hasher.hexdigest() == user.password:
return redirect('sub')
except User.DoesNotExist:
pass
return render(request, 'demo/login.html',
{'hint': '用户名或密码错误!'})
def register(request):
if request.method == 'GET':
return render(request, 'demo/register.html', {})
else:
try:
user = User()
user.username = request.POST['username']
if request.POST.get('password1') == request.POST.get('password2'):
user.password = request.POST['password1']
user.email = request.POST['email']
user.save()
return render(request, 'demo/login.html',
{'hint': '注册成功请登录!'})
else:
return render(request, 'demo/register.html',
{'hint': '验证密码失败,请重新输入!'})
except:
return render(request, 'demo/register.html',
{'hint': '注册失败,请尝试其他用户名!'})
def show_subjects(request):
ctx = {'subjects_list': Subject.objects.all()}
return render(request, 'demo/subject.html', ctx)
def show_teachers(request, no):
teachers = Teacher.objects.filter(subject__no=no)
ctx = {'teachers_list': teachers}
return render(request, 'demo/teacher.html', ctx)
def make_comment(request, no):
ctx = {'code': 200}
try:
teacher = Teacher.objects.get(pk=no)
if request.path.startswith('/good'):
teacher.good_count += 1
ctx['result'] = f'好评({teacher.gcount})'
else:
teacher.bad_count += 1
ctx['result'] = f'差评({teacher.bcount})'
teacher.save()
except Teacher.DoesNotExist:
ctx['code'] = 404
return HttpResponse(json.dumps(ctx),
content_type='application/json; charset=utf-8')
注意:登录时密码的验证,返回的页面路径、提示内容hint;注册是二次密码一致性的验证(可以用JavaScript在模板中验证,还没搞明白。)
4.url映射的修改:
urlpatterns = [
path('', views.login),
path('login/', views.login),
path('register/', views.register),
path('subjects/', views.show_subjects, name='sub'),
path('subjects//', views.show_teachers),
path('good//', views.make_comment),
path('bad//', views.make_comment),
path('admin/', admin.site.urls),
]
至此,用户注册并登陆成功之后,即可看到subject页面。