2.4 用户注册
此前所使用的账户是通过超级管理员设置的,这种方式通常被某些比较封闭的网站采用,比如某机构的内部管理网站,目的是要严格审查用户身份。对于社会性网站,一般允许通过自行注册的方式成为网站用户。

2.4.1 简单注册
最简单的就是注册用户名和密码,利用原有的数据库,即Django默认的用户数据模型。
实现用户注册功能与实现登录功能类似,都要填写表单。所以,编写一个表单类是必须的。编辑./account/forms.py文件,增加一个注册用户的表单类。
1 from django import forms 2 from django.contrib.auth.models import User #① 3 ...... 4 5 class RegistrationForm(forms.ModelForm): #② 6 password = forms.CharField(label="Password",widget=forms.PasswordInput) 7 password2 = forms.CharField(label="Confirm Password",widget=forms.PasswordInput) 8 9 class Meta: #③ 10 model = User #④ 11 fields = ("username","email") 12 13 def clean_password2(self): #⑤ 14 cd = self.cleaned_data 15 if cd['password'] !=cd['password2']: 16 raise forms.validationError("passwords do not match.") 17 return cd['password2']
语句①引入了Django默认的用户模型User类,在这个表单类中就应用User模型,不需要再新建用户数据模型了。
前面的登录表单类这种曾经继承了forms.Form类,语句②中的forms.ModelForm是forms里面的另外一个常用的类,这两个类在应用上是有区别的。一般情况下,如果要将表单中的数据写入数据库表或者修改某些记录的值,就要让表单类继承ModelForm类;如果提交表单之后,不会对数据库进行修改,则继承Form类。其实,从名称也能看出来,ModelForm是和该应用的Model有关的表单。
语句③是一个内部类,其中我们需要声明本表单类所应用的数据模型,也就是将来表单的内容会写入到哪个数据库表中的哪些记录里面,这就是语句④的作用。表单类中的属性和数据模型类中的属性一一对应,不必在表单中向数据模型中的所有字段赋值(或者不需要把数据库表中所有的字段写入数据),可以用fields = ("username","email")来说明这里所选用的属性(数据库表中的字段),或者用exclude列表说明所排出的属性。
password和password2两个密码属性是为了让用户确认自己所设置的密码,这两个属性是在这里重新定义的。如同前面LoginForm表单里面定义的两个属性,这里定义了就意味着覆盖或者不需要在内部类Meta中声明数据模型中的字段。
在类内部还定义了语句⑤中的方法clean_password2(),这个方法的作用是检验用户所输入的两个密码是否一致。检查的动作在我们调用表单实例对象的is_valid()方法时会被执行。以“clean_+属性名称”命名方式所创建的方法。
数据模型类(User)和表单类(RegistrationForm)都已经有了,接下来就是试图函数和相应的前端模板。
编辑./account/views.py文件,编写注册的视图函数。
1 {% extends "base.html" %} 2 3 {% load staticfiles %} 4 5 {% block title %}register user{% endblock %} 6 7 {% block content %} 8 <div class="row text-center vertical-middle-sm"> 9 <h1>Register</h1> 10 <p>If you are a user, <strong><a href="{% url 'account:user_login' 11 %}">Login</a> </strong>,please</p> 12 <p>or register.</p> 13 <form class="form-horizontal" action="." method="post">{% csrf_token %} 14 <div class="form-group"> 15 <label for="{{ form.username.id_for_label }}" class="col-md-5 16 control-label">Username</label> 17 <div class="col-md-6 text-left">{{ form.username }}</div> 18 </div> 19 20 <div class="form-group"> 21 <label for="{{ form.email.id_for_label }}" class="col-md-5 22 control-label">Email</label> 23 <div class="col-md-6 text-left">{{ form.email }}</div> 24 </div> 25 26 <div class="form-group"> 27 <label for="{{ form.password.id_for_label }}" class="col-md-5 28 control-label">Password</label> 29 <div class="col-md-6 text-left">{{ form.password }}</div> 30 </div> 31 <div class="form-group"> 32 <label for="{{ form.password.id_for_label }}" class="col-md-5 33 control-label">Confirm Password</label> 34 <div class="col-md-6 text-left">{{ form.password2 }}</div> 35 </div> 36 <div class="form-group"> 37 <label for="{{ profile.birth.id_for_label }}" class="col-md-5 38 control-label">Brith Date</label> 39 <div class="col-md-6 text-left">{{ profile.birth }}</div> 40 </div> 41 <div class="form-group"> 42 <label for="{{ profile.phone.id_for_label }}" class="col-md-5 43 control-label">Phone</label> 44 <div class="col-md-6 text-left">{{ profile.phone }}</div> 45 </div> 46 <input type="submit" class="btn btn-primary btn-lg" value="REGISTER"> 47 </form> 48 </div> 49 {% endblock %}
检查Django服务是否运行了,然后打开浏览器,访问http://127.0.0.1:8000/account/register/,打开页面如下图所示


注册成功了,用户信息将被保存到数据库中。查看一下数据库表,会看到新注册的用户信息。

查看auth_user这个内置的用户数据库表,用户id为5的那个用户是刚刚注册的,再来看跟它具有一对一关系的、我们自定义的account_userprofile数据库表,如下图所示。

这里记录了对应的用户id及新增加的birth和phone两个字段。
2.4.3 管理新增的注册内容
当我们增加用户注册信息后,所增加的内容能不能也在超级管理员界面中进行集中管理呢?要实现这个功能,需要对./account/admin.py文件进行编辑,代码如下。
1 from django.contrib import admin 2 from .models import UserProfile 3 # Register your models here. 4 class UserProfileAdmin(admin.ModelAdmin): 5 list_display = ('user','birth','phone') 6 list_filter = ("phone",) 7 8 admin.site.register(UserProfile, UserProfileAdmin)
保存代码,刷新http://127.0.0.1:8000/admin/,会看到如下图所示的界面。

其中,ACCOUNT选项和其下面的User profiles选项是由admin.py中的代码新增加的,单击User profiles选项,可以看到对新增加的注册内容的管理,如下图所示。

对刚才编写的UserProfileAdmin()函数进行简要说明。
- list_display属性的作用是列出列表中的项目。注意这个属性的名称不能改变,后面所有类似的属性也是如此。
- list_filter的作用是规定网页右边FILTER的显示内容,读者可以根据这里的电话号码过滤显示列表的内容。
当然,作为超级管理员也有权限增加用户的信息,单击“ADD USER PROFILE”按钮可以进行增加用户信息的操作。
通过以上操作看出,在admin.py文件中所编写的代码,主要是将某些内容注册到后端管理界面,从而让超级管理员对该内容进行管理。
读者在自己的项目中,可以使用类似本项目的方式实现,也可以不使用Django默认的User表,完全自己来编写用户管理相关应用,只不过要考虑有关的周边问题,不仅仅是把用户的信息保存到数据库,比如session等。
2.4.4 知识点
1、模型:字段属性类型
数据模型类(Model)依然是Python中的类,可以在其中命名属性(变量)和方法。每个属性(变量)对应着数据库中的一个字段,所以在Django的数据模型类中,也将变量称为字段。数据库中的字段要有自己的属性,那么数据模型类中的字段也应该有属性,这些属性在django.db.models中,比如title=models.CharField(max_length=300)
在默认情况下,Django会为每个数据模型类设置一个自增的id字段,并将其作为该数据库表的主见,因此这个字段不需要在数据模型类中写出来。当然,开发也可在数据模型类中自行指定主键,方法是在该字段属性中增加primary_key=True。除这个默认的id字段外,其他字段都需要开发者在数据模型类中声明其名称和属性。
- CharField:用于保存字符串,在使用时一定要声明字符串的长度。
- TextField:与CharField一样,区别在于保存的字符串长度是无限的(严格说应该受制于数据库程序和硬件系统),通常用于保存较大文本。
- EmailField、URLField:都继承了CharField,只不过其中包含了验证它们的值是否是E-mail和URL的方法。将某个字段设置为该类型,不需要再编写对写入数据的验证方法。
- FieldField:表示该字段接收上传文件,同时将上传的文件保存到服务器中。
- DateField、DateTimeField:用于保存时间,有一个常用参数auto_now_add,如果auto_now_add=True,那么当数据模型实例被保存时,当前时间将自动被存储,而不需要为该字段进行赋值。
2、用户注册拓展知识
Django默认的django.contrib.auth应用中有登录login()方法,但没用户注册的方法。本节介绍了一种简单的用户注册过程,所采用的数据模型是Django内置的用户管理应用中的数据模型(from django.contrib.auth.models import User),也就是将用户这车信息存入上节所使用的数据库表中。
虽然Django没有默认的注册功能,但是注册是网站开发所不可或缺的。就出现了很多第三方的Django应用,比如针对注册的django-registration就是一个典型例子,读者可以访问官方网站(http://django-registration.readthedocs.io/en/2.0.4/install.html)了解这个应用的使用方法,可以按照网站的说明自己进行调试。
现在是社交媒体泛滥的时代,很多网站都支持用社交媒体账号登录,用Django开发的网站项目当然也能做到。要完成这个工作,开发者可以根据某个社交媒体官方提供的API,结合自己的网站项目完成。Django继承了Python的优良传统---开发,这就让很多人有机会为Django提供“轮子”。所以,如果需求是某种比较通用的功能,可以先在网站找找有没有“轮子”。Django Social Auth就是一个专门用于社交媒体账户登录Django项目的第三方应用。github.com上的源码地址是https://github.com/omab/django-social-auth,其中有较为详细的说明。

浙公网安备 33010602011771号