点赞功能
1.Ajax技术来实现“好评”和“差评”
from django.contrib import admin
from django.urls import path
from vote import views
urlpatterns = [
path('', views.show_subjects),
path('teachers/', views.show_teachers),
path('praise/', views.prise_or_criticize),
path('criticize/', views.prise_or_criticize),
path('admin/', admin.site.urls),
]
2.设计视图函数praise_or_criticize
该视图函数通过Django封装的JsonResponse类将字典序列化成JSON字符串作为返回给浏览器的响应内容。
def praise_or_criticize(request):
"""好评"""
try:
tno = int(request.GET['tno'])
teacher = Teacher.objects.get(no=tno)
if request.path.startswith('/prise'):
teacher.good_count += 1
else:
teacher.bad_count += 1
teacher.save()
data = {'code': 200, 'hint': '操作成功'}
except (KeyError, ValueError, Teacher.DoseNotExist):
data = {'code': 404, 'hint': '操作失败'}
return JsonResponse(data)
3.修改显示老师信息的模板页,引入jQuery库来实现事件处理、Ajax请求和DOM操作。
<script src="{% static 'js/jquery.min.js' %}"></script>
<script>
$(() => {
$('.comment>a').on('click', (evt) => {
evt.preventDefault();
let a = $(evt.target)
let span = a.next()
$.getJSON(a.attr('href'), (json) => {
if (json.code == 200) {
span.text(parseInt(span.text()) + 1)
<!--点击标签时,服务器数据由服务器通过views+1,同步刷新页面数据html页面+1-->
} else {
alert(json.hint)
}
})
})
})
</script>
表单应用
1.添加用户模型
class User(models.Model):
"""用户"""
no = models.AutoField(primary_key=True, verbose_name='编号')
username = models.CharField(max_length=20, unique=True, verbose_name='用户名')
password = models.CharField(max_length=32, verbose_name='密码')
regdate = models.DateTimeField(auto_now_add=True, verbose_name='注册时间')
class Meta:
db_table = 'tb_user'
verbose_name_plural = '用户'
2.生成迁移和执行迁移操作,在数据库中创建对应的用户表。
python manage.py makemigrations 应用名
python manage.py migrate
3.定制简单注册模板页面,使用了模板指令{% csrf_token %}为表单添加一个隐藏域,设置了免除CSRF令牌
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户注册</title>
<style>/* 此处省略层叠样式表选择器 */</style>
</head>
<body>
<h1>用户注册</h1>
<hr>
<p class="hint">{{ hint }}</p>
<form action="/register/" method="post">
{% csrf_token %}
<div class="input">
<label for="username">用户名:</label>
<input type="text" id="username" name="username">
</div>
<div class="input">
<label for="password">密码:</label>
<input type="password" id="password" name="password">
</div>
<div class="input">
<label for="repassword">确认密码:</label>
<input type="password" id="repassword" name="repassword">
</div>
<div class="input">
<input type="submit" value="注册">
<input type="reset" value="重置">
</div>
</form>
<a href="//www.greatytc.com/login">返回登录</a>
</body>
</html>
4.利用Django框架封装的表单功能来对用户输入的有效性进行检查,定义了一个与User模型绑定的表单,对长度进行限制,clean_方法自定义验证规则二次验证,做MD5摘要处理
def to_md5_hex(message):
return hashlib.md5(message.encode()).hexdigest()
USERNAME_PATTERN = re.compile(r'\w{4,20}')
class RegisterForm(forms.ModelForm):
repassword = forms.CharField(min_length=8, max_length=20)
def clean_username(self):
username = self.cleaned_data['username']
if not USERNAME_PATTERN.fullmatch(username):
raise ValidationError('用户名由字母、数字和下划线构成且长度为4-20个字符')
return username
def clean_password(self):
password = self.cleaned_data['password']
if len(password) < 8 or len(password) > 20:
raise ValidationError('无效的密码,密码长度为8-20个字符')
return to_md5_hex(self.cleaned_data['password'])
def clean_repassword(self):
repassword = to_md5_hex(self.cleaned_data['repassword'])
if repassword != self.cleaned_data['password']:
raise ValidationError('密码和确认密码不一致')
return repassword
class Meta:
model = User
exclude = ('no', 'regdate')
5.新增一个视图函数实现用户注册的功能。
def register(request):
page, hint = 'register.html', ''
if request.method == 'POST':
form = RegisterForm(request.POST)
if form.is_valid():
form.save()
page = 'login.html'
hint = '注册成功,请登录'
else:
hint = '请输入有效的注册信息'
return render(request, page, {'hint': hint})
6.用户发起GET请求,将直接跳转到注册的页面,以POST方式提交注册表单,创建自定义的注册表单对象并获取用户输入,通过表单对象的is_valid方法对表单进行验证,定义的RegisterForm继承自ModelForm,因此也可以直接使用表单对象的save方法来保存模型。
7.注册请求的URL配置
from django.contrib import admin
from django.urls import path
from vote import views
urlpatterns = [
path('', views.show_subjects),
path('captcha/', views.get_captcha),
path('teachers/', views.show_teachers),
path('prise/', views.praise_or_criticize),
path('criticize/', views.praise_or_criticize),
path('login/', views.login, name='login'),
path('register/', views.register, name='register'),
path('admin/', admin.site.urls),
]
8.定制简单登录页
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户登录</title>
<style>/* 此处省略层叠样式表选择器 */</style>
</head>
<body>
<h1>用户登录</h1>
<hr>
<p class="hint">{{ hint }}</p>
<form action="//www.greatytc.com/login/" method="post">
<input type="hidden" name="backurl" value="{{ backurl }}">
{% csrf_token %}
<div class="input">
<label for="username">用户名:</label>
<input type="text" id="username" name="username">
</div>
<div class="input">
<label for="password">密码:</label>
<input type="password" id="password" name="password">
</div>
<div class="input captcha">
<label for="captcha">验证码:</label>
<input type="text" id="captcha" name="captcha">
<img src="/captcha/" width="120">
</div>
<div class="input">
<input type="submit" value="登录">
<input type="reset" value="重置">
</div>
</form>
<a href="/register">注册新用户</a>
</body>
</html>