这几天正好学了Flask的用户注册登录功能设计,发现与Django的使用特别类似,所以学习Flask的同时也加强了我对Django表单的印象。正好网站搭建也差不多更新到用户操作部分了,就索性把Django表单相关知识再推进一下。其实要加入用户操作功能,也可以直接在模板页面中加上form标签,然后在视图中利用requets.POST.get来接收键值,最后保存在数据库中,所以不是非要使用Django的表单功能才能设计。使用表单是因为表单的确能简化用户在提交用户信息的相关处理,如输入内容不能为空,邮箱必须带有@字符等,这些验证表单的合法性最后都可以交给Django的表单来执行
因为在Django中,有比较全的用户模块,所以我没有另外去创建models.py来定义用户的模型,这已经在Django中实现了。我只创建了forms.py用来加入表单字段,另外引用了Django自带的User类。用户的注册登录功能可以比较好的涵盖form表单的相关知识点,常用的form字段定义在官方文档都有说明:表格字段
用户注册
1.我在注册表单中,需要用户名,邮箱,密码等输入
from django import forms # django表单功能
from django.contrib.auth.models import User
class RegForm(forms.Form):
"""
用户注册表单
"""
# 用户名
username = forms.CharField(label='用户名',
max_length=30,
min_length=3,
widget=forms.TextInput(
attrs={'class': 'form-control', 'placeholder': '请输入用户名'}))
# 邮箱
email = forms.EmailField(label='邮箱',
widget=forms.EmailInput(
attrs={'class': 'form-control', 'placeholder': '请输入邮箱'}))
# 密码
password = forms.CharField(label='密码',
min_length=6,
widget=forms.PasswordInput(
attrs={'class': 'form-control', 'placeholder': '请输入密码'}))
# 再次输入密码
password_again = forms.CharField(label='再输入一次密码',
min_length=6,
widget=forms.PasswordInput(
attrs={'class': 'form-control', 'placeholder': '再输入依次密码'}))
其中包含了一些属性设置,用来规范表单的显示
2.定义好表单之后,除了表单自动验证的部分外,还需要另外手动添加对字段的验证,如用户名,邮箱是否会与数据库已有的用户重复,还有第二次输入的密码与第一次输入的密码是否一致,以确保用户输入了正确的密码,所以还需在RegForm类中加入一些方法
def clean_username(self):
"""
清洗输入的用户名
:return: 清洗后的用户名
"""
username = self.cleaned_data['username']
if User.objects.filter(username=username).exists():
raise forms.ValidationError('用户名已存在')
return username
def clean_email(self):
"""
清洗输入的邮箱
:return: 清洗后的邮箱
"""
email = self.cleaned_data['email']
if User.objects.filter(email=email).exists():
raise forms.ValidationError('邮箱已存在')
return email
def clean_password_again(self):
"""
清洗第二次输入的密码
:return: 输入一致的密码
"""
password = self.cleaned_data['password']
password_again = self.cleaned_data['password_again']
if password != password_again:
raise forms.ValidationError('两次输入的密码不一致')
return password
其中forms.ValidationError是抛出表单错误的信息
3.在views.py中添加用户注册的处理,常用的Forms API:Working with forms
from django.shortcuts import redirect, render
from django.contrib import auth # auth模块是Django提供的标准权限管理系统,可以提供用户身份认证, 用户组和权限管理。
from django.urls import reverse # 反向解析
from django.contrib.auth.models import User
from .forms import LoginForm, RegForm
def register(request):
"""
用户注册功能相关处理
:param request: 请求对象
:return: 注册成功返回首页,失败返回注册表单
"""
if request.method == 'POST':
reg_form = RegForm(request.POST)
# 判断是否有效
# 验证通过
if reg_form.is_valid():
# 第一种注册方法
username = reg_form.cleaned_data['username']
email = reg_form.cleaned_data['email']
password = reg_form.cleaned_data['password']
# 创建用户
user = User.objects.create_user(username, email, password)
user.save()
# 登录用户
user = auth.authenticate(username=username, password=password)
auth.login(request, user)
return redirect(request.GET.get('from', reverse('blog:home')))
'''
# 第二种注册方法
user = User()
user.username = username
user.email = email
user.set_password(password)
user.save()
'''
# 验证失败
else:
# login_form对象会自动创建表单
reg_form = RegForm()
context = {'reg_form': reg_form}
return render(request, 'user/register.html', context)
4.注册页面如下
<div class="col-xs-11 col-sm-5 col-lg-4 col-sm-offset-4 blog-border side-info">
<h4>欢迎注册</h4>
<form action="" method="POST">{% csrf_token %}
{% for field in reg_form %}
{# label去冒号 #}
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
{{ field }}
<p class="text-danger">{{ field.errors.as_text }}</p>
{% endfor %}
{# 错误信息标红 #}
<span class="pull-left text-danger">{{ login_form.non_field_errors }}</span>
{# <span>用户名:</span> #}
{# <input type="text" name="username"> #}
{# <span>密码:</span> #}
{# <input type="password" name="password"> #}
<span style="font-weight: bold;">已有帐号?<a style="color: #337ab7;" href="{% url 'user:login' %}">点击登录</a></span>
<input class="btn btn-primary pull-right" style="margin-bottom: 0.5em" type="submit" value="注册">
</form>
{% if user.is_authenticated %}
<script type="text/javascript">
window.location.href = '/';
</script>
{% else %}
{% endif %}
</div>
5.最后在urls.py添加
url(r'^register/', views.register, name='register'),
用户登录
1.与RegForm类似,需要用户名和密码,少了一些验证,只要判断在用户表中是否含有这个用户名
from django import forms # django表单功能
from django.contrib import auth
from django.contrib.auth.models import User
class LoginForm(forms.Form):
"""
用户登录表单
"""
# 用户名
username = forms.CharField(label='用户名',
widget=forms.TextInput(
attrs={'class': 'form-control', 'placeholder': '请输入用户名'}))
# 密码
password = forms.CharField(label='密码',
widget=forms.PasswordInput(
attrs={'class': 'form-control', 'placeholder': '请输入密码'}))
def clean(self):
"""
清洗输入不合格的表单
:return: 清洗后的数据
"""
username = self.cleaned_data['username']
password = self.cleaned_data['password']
user = auth.authenticate(username=username, password=password)
# 判断用户是否存在
if user is None:
raise forms.ValidationError('用户名或密码不正确')
else:
self.cleaned_data['user'] = user
return self.cleaned_data
2.用户登录的视图处理
from django.shortcuts import redirect, render
from django.contrib import auth # auth模块是Django提供的标准权限管理系统,可以提供用户身份认证, 用户组和权限管理。
from django.urls import reverse # 反向解析
from .forms import LoginForm
def login(request):
"""
用户登录逻辑处理
:param request:
:return: 登录视图
"""
if request.method == 'POST':
login_form = LoginForm(request.POST)
# 判断是否有效
# 验证通过
if login_form.is_valid():
# cleaned_data是一个字典,包含了字段的信息
# 表示清理过或者整理过的数据,比较干净的数据
# username = login_form.cleaned_data['username']
# password = login_form.cleaned_data['password']
# user = auth.authenticate(username=username, password=password)
# 判断用户是否存在
# if user is not None:
user = login_form.cleaned_data['user']
auth.login(request, user)
# 如果没有获取到源页面就返回到首页
referer = request.GET.get('from', reverse('blog:blog'))
return redirect(referer)
# 验证失败
else:
# login_form对象会自动创建表单
login_form = LoginForm()
context = {'login_form': login_form}
return render(request, 'user/login.html', context)
3.创建视图模板
<div class="col-xs-11 col-sm-5 col-lg-4 col-sm-offset-4 blog-border side-info">
<h4>用户登录</h4>
<form action="" method="POST">
{% csrf_token %}
{% for field in login_form %}
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
{{ field }}
<p class="text-danger">{{ field.errors.as_text }}</p>
{% endfor %}
{# 错误信息标红 #}
<span class="pull-left text-danger">{{ login_form.non_field_errors }}</span>
{# <span>用户名:</span> #}
{# <input type="text" name="username"> #}
{# <span>密码:</span> #}
{# <input type="password" name="password"> #}
<span style="font-weight: bold;">没有帐号?<a style="color: #337ab7;" href="{% url 'user:register' %}">点击注册</a></span>
<input class="btn btn-primary pull-right" style="margin-bottom: 0.5em" type="submit" value="登录">
</form>
{% if user.is_authenticated %}
<script type="text/javascript">
window.location.href = '/';
</script>
{% else %}
{% endif %}
</div>
4.在url.py添加
url(r'^login/', views.login, name='login'),
5.还可以使用如下方法显示用户信息
<p>加入时间:{{ user.date_joined }}</p>
<p>上次登录时间:{{ user.last_login}}</p>
原文出处:https://www.jzfblog.com/detail/105,文章的更新编辑以此链接为准。欢迎关注源站文章!