一、前言
这几天正好学了Flask的用户注册登录功能设计,发现与Django的使用特别类似,所以学习Flask的同时也加强了我对Django表单的印象。正好网站搭建也差不多更新到用户操作部分了,就索性把Django表单相关知识再推进一下。其实要加入用户操作功能,也可以直接在模板页面中加上form标签,然后在视图中利用requets.POST.get来接收键值,最后保存在数据库中,所以不是非要使用Django的表单功能才能设计。使用表单是因为表单的确能简化用户在提交用户信息的相关处理,如输入内容不能为空,邮箱必须带有@字符等,这些验证表单的合法性最后都可以交给Django的表单来执行。
因为在Django中,有比较全的用户模块,所以我没有另外去创建models.py来定义用户的模型,这已经在Django中实现了。我只创建了forms.py用来加入表单字段,另外引用了Django自带的User类。用户的注册登录功能可以比较好的涵盖form表单的相关知识点,常用的form字段定义在官方文档都有说明:表格字段。
二、用户注册
我在注册表单中,需要用户名,邮箱,密码等输入。
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': '再输入依次密码'}))
其中包含了一些属性设置,用来规范表单的显示。定义好表单之后,除了表单自动验证的部分外,还需要另外手动添加对字段的验证,如用户名,邮箱是否会与数据库已有的用户重复,还有第二次输入的密码与第一次输入的密码是否一致,以确保用户输入了正确的密码,所以还需在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是抛出表单错误的信息,在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) 注册页面如下 <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>
最后在urls.py添加
url(r'^register/', views.register, name='register'),
三、用户登录
与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
用户登录的视图处理。
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)
创建视图模板
<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>
在url.py添加
url(r'^login/', views.login, name='login'),
还可以使用如下方法显示用户信息
<p>加入时间:{{ user.date_joined }}</p> <p>上次登录时间:{{ user.last_login}}</p>
原文出处:https://jzfblog.com/detail/105,文章的更新编辑以此链接为准。欢迎关注源站文章!