(项目)在线教育平台(四)

六、注册功能

1、注册页面配置

  将注册页面register.html前端文件拷贝到项目的templates文件夹内。

  然后修改注册页面register.html初始文件中的静态文件访问路径,修改成{% static '静态文件路径' %}的形式,如下:

  在index.html文件中修改跳转到注册页面的url:

2、第三方工具验证码的配置

  在邮箱注册时,需要生成图片验证码,这就需要借助第三方库django-simple-captcha来实现。

2.1 安装

  在虚拟环境中直接pip install django-simple-captcha

2.2 在setting.py中配置这个库

 1 INSTALLED_APPS = [ 2     'captcha',
 3 ]

2.3 在urls.py中配置验证码的url

1 urlpatterns = [
2     path('captcha/', include('captcha.urls')),  # 验证码
3 ]

2.4 生成数据库中的表

  执行迁移数据库的命令,生成如下一张表:

2.5 在注册页面显示验证码

  首先在form.py文件中加入注册表单验证:

1 from captcha.fields import CaptchaField
2 
3 class RegisterForm(forms.Form):
4     """注册表单验证"""
5     email = forms.EmailField(required=True)
6     password = forms.CharField(required=True, min_length=5)
7     # 验证码字段,可以自定义错误提示信息
8     captcha = CaptchaField()

  然后在前端加入{{ register_form.captcha }}来显示验证码的图片:

  现在刷新注册页面,点击验证码图片后会刷新验证码图片。

3、后端用户注册接口

3.1 编写注册接口

  在users/views.py文件中编写登录的接口:

 1 class RegisterView(View):
 2     """注册"""
 3     def get(self, request):
 4         register_form = RegisterForm()
 5         return render(request, 'register.html', {'register_form': register_form})
 6 
 7     def post(self, request):
 8         register_form = RegisterForm(request.POST)
 9         if register_form.is_valid():
10             #  form表单验证通过,从request请求中获取邮箱
11             user_name = request.POST.get('email', None)
12 
13             # 从UserProfile表中查询邮箱是否存在
14             if UserProfile.objects.filter(email=user_name):
15                 return render(request, 'register.html', {'register_form': register_form, 'msg': '用户已注册'})
16 
17             # 从request中获取密码
18             pass_word = request.POST.get('password', None)
19             # 将注册信息保存数据库
20             user_profile = UserProfile()
21             user_profile.username = user_name
22             user_profile.email = user_name
23             user_profile.is_active = False  # 账户现在是未激活状态,需要邮件激活后才能变为True
24             # 注意,这里密码存储的时候需要加密存储,通过django的make_password方法进行加密
25             user_profile.password = make_password(pass_word)
26             user_profile.save()
27 
28             # 注册完成,返回登录页面
29             return render(request, 'login.html')
30         else:
31             return render(request, 'register.html', {'register_form': register_form})

3.2 添加注册的url

1 from users.views import RegisterView
2 
3 urlpatterns = [
4     path('register/', RegisterView.as_view(), name='register'),  # 注册
5 ]

3.3 发送激活邮件

  通过django的邮件发送模块来发送激活邮件,首先需要在settings.py文件中设置邮件发送服务器:

1 # 发送邮件配置
2 EMAIL_HOST = "smtp.qq.com"  # SMTP服务器主机
3 EMAIL_PORT = 25             # 端口
4 EMAIL_HOST_USER = "779060694@qq.com"       # 邮箱地址
5 EMAIL_HOST_PASSWORD = "dhjuveakiuqibeje"    # 密码
6 EMAIL_USE_TLS= True
7 EMAIL_FROM = "779060694@qq.com"            # 邮箱地址

  以QQ邮箱为例,作为发送邮件的服务器,EMAIL_HOST_PASSWORD的密码是通过下面的生成授权码生成的,设置如下:

  然后编写邮件代码,在apps下新建包utils,在该包下新建send_email.py文件,在该文件下编写邮件代码:

 1 from random import Random
 2 
 3 from django.core.mail import send_mail
 4 
 5 from users.models import EmailVerifyRecord
 6 from MxOnline.settings import EMAIL_FROM
 7 
 8 
 9 def random_str(random_length=8):
10     str = ''
11     chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
12     length = len(chars)-1
13     random  = Random()
14     for x in range(random_length):
15         str += chars[random.randint(0, length)]
16     return str
17 
18 
19 def send_register_email(email, send_type='register'):
20     """发送注册邮件"""
21     # 发送之前先保存到数据库,需要查询链接是否存在
22     email_record = EmailVerifyRecord()
23 
24     # 生成随机的code放到连接中
25     code = random_str(16)
26     email_record.code = code
27     email_record.email = email
28     email_record.send_type = send_type
29     email_record.save()
30 
31     # 定义邮件内容
32     email_title = ''
33     email_body = ''
34     if send_type == 'register':
35         email_title = '知能网注册激活链接'
36         email_body = '请点击下面的链接激活你的账号:http://127.0.0.1:8000/active/{}'.format(code)
37 
38         # 发送邮件
39         send_status = send_mail(email_title, email_body, EMAIL_FROM, [email])
40         if send_status:
41             pass

  在发送邮件之前,需要修改注册接口,在注册数据保存之后,发送邮件:

 1 class RegisterView(View):
 2     """注册"""
 3     def get(self, request):
 4         register_form = RegisterForm()
 5         return render(request, 'register.html', {'register_form': register_form})
 6 
 7     def post(self, request):
 8         register_form = RegisterForm(request.POST)
 9         if register_form.is_valid():
10             #  form表单验证通过,从request请求中获取邮箱
11             user_name = request.POST.get('email', None)
12 
13             # 从UserProfile表中查询邮箱是否存在
14             if UserProfile.objects.filter(email=user_name):
15                 return render(request, 'register.html', {'register_form': register_form, 'msg': '用户已注册'})
16 
17             # 从request中获取密码
18             pass_word = request.POST.get('password', None)
19             # 将注册信息保存数据库
20             user_profile = UserProfile()
21             user_profile.username = user_name
22             user_profile.email = user_name
23             user_profile.is_active = False  # 账户现在是未激活状态,需要邮件激活后才能变为True
24             # 注意,这里密码存储的时候需要加密存储,通过django的make_password方法进行加密
25             user_profile.password = make_password(pass_word)
26             user_profile.save()
27 
28             # 发送注册激活邮件
29             send_register_email(user_name, 'register')
30 
31             # 注册完成,返回登录页面
32             return render(request, 'login.html')
33         else:
34             return render(request, 'register.html', {'register_form': register_form})

  现在,就可以在注册时,发送注册激活链接了。

3.4 激活用户

  我们需要新建一个激活失败需要返回的页面,在templates下新建active_fail.html文件:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8     <p style="color: red;">链接失效</p>
 9 </body>
10 </html>

  用户在注册之后,不能直接登录,需要点击邮件中的激活链接连激活账号,需要在users/views.py文件中编写激活账户的接口:

 1 class ActiveUserView(View):
 2     """激活账户"""
 3     def get(self, request, active_code):
 4         # 查询邮箱验证记录是否存在,存在则激活用户
 5         all_record = EmailVerifyRecord.objects.filter(code=active_code)
 6         if all_record:
 7             for record in all_record:
 8                 # 获取对应的邮箱和其用户,将is_active置为True
 9                 email = record.email
10                 user = UserProfile.objects.get(email=email)
11                 user.is_active = True
12                 user.save()
13         else:
14             # 不存在,返回失败页面
15             return render(request, 'active_fail.html')
16         # 激活成功,返回登录页面
17         return render(request, 'login.html')

  然后配置激活链接的url:

1 from users.views import ActiveUserView
2 
3 urlpatterns = [
4     re_path('active/(?P<active_code>.*)/', ActiveUserView.as_view(), name='user_active'),  # 激活用户
5 ]

  现在就可以注册成功了,在登录的时候需要加一个条件,也就是激活账户才能登录:

 1 class LoginView(View):
 2     """登录"""
 3     def get(self, request):
 4         return render(request, 'login.html')
 5 
 6     def post(self, request):
 7         # form实例化
 8         login_form = LoginForm(request.POST)
 9         if login_form.is_valid():
10             # form验证通过,获取用户提交的用户名和密码
11             user_name = request.POST.get('username', None)
12             pass_word = request.POST.get('password', None)
13 
14             # 通过django的authenticate方法获取user对象,也就是验证用户是否存在
15             user = authenticate(username=user_name, password=pass_word)
16 
17             if user is not None:
18                 if user.is_active:
19                     # 只有激活用户才能登录
20                     # 验证通过,通过django的login方法去登录,然后返回首页
21                     login(request, user)
22                     return render(request, 'index.html')
23                 else:
24                     # 验证不通过,返回登录页面,并将错误信息返回去显示
25                     return render(request, 'login.html', {'msg': '用户名或密码错误', 'login_form': login_form})
26             else:
27                 # 验证不通过,返回登录页面,并将错误信息返回去显示
28                 return render(request, 'login.html', {'msg': '用户名或密码错误', 'login_form': login_form})
29         else:
30             return render(request, 'login.html', {'login_form': login_form})

4、前端错误提示信息修改

  注册失败后,前端需要有错误信息提示,register.html修改地方如下:

  

原文地址:https://www.cnblogs.com/Sweltering/p/9968603.html