一、登陆注册实现思路
- 创建模型类(映射生成数据表)
- 创建登陆模板(创建注册模板)
- 创建视图函数
- 配置url
二、创建模型生成数据表
① 在teacher/models.py中
from django.db import models
class User(models.Model):
username = models.CharField(verbose_name='用户名', max_length=10, unique=True)
password = models.CharField(max_length=8)
phone = models.CharField(max_length=11, unique=True)
② 生成迁移文件并执行迁移
三、form表单的引用
- 登录和注册页面都会用到form表单来提交数据
- 当数据提交到后台后,需要在视图函数中去验证数据的合法性
- django提供了一个form表单的功能,这个表单可以用来验证数据的合法性,还可以用来生成HTML代码
- 这次的登录注册案例就用django自带的form来生成前端页面以及验证数据
四、django form表单的使用
① 在app目录下创建一个forms.py的文件,然后在里面写表单
② 表单是通过类来实现的,继承自forms.Form,然后在里面定义要验证的字段
③ 在表单中,创建字段跟模型是一摸一样的,但是没有null=True或者blank=True等这几种参数了,有的参数是required=True/False(可填可不填)
④ 使用is_valid()方法可以验证用户提交的数据是否合法,而且HTML表单元素的name属性必须和django中的表单的字段名保持一致,否则匹配不到
⑤ is_bound属性:用来表示form是否绑定了数据,如果绑定了,则返回True,否则返回False
⑥ cleaned_data:这个是在is_valid()返回True的时候,保存用户提交上来的数据
案例:
① 在teacher/forms.py中:
from django import forms
import re
class RegisterForm(forms.Form):
username = forms.CharField(label='用户名', max_length=10, min_length=4)
password = forms.CharField(label='密码', max_length=8, min_length=4,
widget=forms.PasswordInput(attrs={'placeholder': '请输入密码'}),
error_messages={
'max_length': '密码长度不得超过8位',
'min_length': '密码长度不得小于6位',
})
password_repeat = forms.CharField(label='请再次输入密码', widget=forms.PasswordInput())
phone = forms.CharField(label='手机号', max_length=11, min_length=11)
def clean_phone(self):
num = self.cleaned_data.get('phone')
ret = re.match(r'^1[35678]\d{9}$', num)
if not ret:
raise forms.ValidationError('手机号格式不正确!!!')
return num
def clean(self):
cleaned_data = super().clean()
password = cleaned_data['password']
password_repeat = cleaned_data['password_repeat']
if password != password_repeat:
raise forms.ValidationError('两次输入的密码不一致')
class LoginForm(forms.Form):
username = forms.CharField(label='用户名', max_length=10, min_length=4)
password = forms.CharField(label='密码', max_length=8, min_length=4, widget=forms.PasswordInput())
form表单中的一些参数说明:
<1>widget:负责渲染网页HTMl表单的输入元素和提取提交的原始数据
<2>attrs:包含渲染后的widget将要设置的HTML属性
<3>error_messages:报错信息
<4>label: form表单渲染后label标签中的内容
注:虽然form表单可以生成前端页面,但这个功能实际用的少,因为看起来不太美观,主要是用form表单的验证功能
② 在teacher/views.py中:
from django.shortcuts import render, redirect, reverse
from django.http import HttpResponse
from .models import User
from .forms import RegisterForm, LoginForm
def index(request):
username = request.session.get('username', '')
return render(request, 'teacher/index.html', context={'username': username})
def login(request):
if request.method == 'GET':
form = LoginForm()
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
user = User.objects.filter(username=username, password=password)
if user:
request.session['username'] = username
return redirect(reverse('teacher:index'))
else:
return HttpResponse('用户名或密码错误!!!')
else:
return HttpResponse('登录失败!!!')
return render(request, 'teacher/login.html', context={'form': form})
def logout(request):
request.session.flush()
return redirect('teacher:index')
def register(request):
if request.method == 'GET':
form = RegisterForm()
else:
form = RegisterForm(request.POST)
if form.is_valid():
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
phone = form.cleaned_data.get('phone')
user = User.objects.filter(username=username)
if user:
return HttpResponse('此用户名已存在!!!')
else:
User.objects.create(username=username, password=password, phone=phone)
request.session['username'] = username
return redirect(reverse('teacher:index'))
return render(request, 'teacher/register.html', context={'form': form})
③ 在teacher/urls.py中
from django.urls import path
from . import views
app_name = 'teacher'
urlpatterns = [
path('index/', views.index, name='index'),
path('login/', views.login, name='login'),
path('logout/', views.logout, name='logout'),
path('register/', views.register, name='register'),
]
④ 在teacher/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>index page</title>
</head>
<body>
{% if username %}
欢迎 <span style="color: orange">{{ username }}</span>登录!!!
<a href="{% url 'teacher:logout' %}">退出登录</a>
{% else %}
您还未登录!!!
<a href="{% url 'teacher:login' %}">登录</a>
还未注册?请先<a href="{% url 'teacher:register' %}">注册</a>
{% endif %}
</body>
</html>
⑤ 在student/login.html中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>login page</title>
</head>
<body>
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="登录">
</form>
</body>
</html>
⑥ 在student/register.html中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>register page</title>
</head>
<body>
<form action="" method="post">
{% csrf_token %}
{% for error in form.errors %}
<p style="color: red">{{ error }}</p>
{% endfor %}
{{ form.as_p }}
<input type="submit" value="注册">
</form>
</body>
</html>
⑦ 在浏览器中访问:
点击注册后,填好数据进行注册,先来一遍合法的!
此时的数据是已经入库了的
由于设置了session,注册后自动登录了!!此时再点退出登录试试
退出登录后,由于清除了session,因此登录状态已不在
填好用户名和密码,点击登录
可以看到,又回到了之前的页面!!!
五、模型表单的使用
① 在之前的student/forms.py中添加
from .models import User
class UserForm(forms.ModelForm):
class Meta:
# 指定模型
model = User
# 指定展示字段,也可用exclude来排除
fields = ['username', 'password', 'phone']
② 在student/views.py中
from .forms import UserForm
def index(request):
username = request.session.get('username', '')
user_form = UserForm()
return render(request, 'teacher/index.html', context={'username': username, 'user_form': user_form})
③ 在浏览器中访问,结果如下图所示
这里password跟phone之所以显示英文是跟models中字段设置的verbose_name有关,效果跟表单差不多,使用起来相对简单!