Django实战项目-学习任务系统-用户注册
接着上期代码框架,开发第2个功能,用户注册,在原有用户模型基础上,增加一个学生用户属性表,用来关联学生用户的各种属性值,这个属性表是参考网络小说里系统属性值设计的,方便直观了解用户的能力高低,等级以及积分值等信息。
第一步:编写第二个功能-用户注册
1,编辑模型文件:
./mysite/study_system/models.py:
class StudyUserAttribute(models.Model): user = models.OneToOneField(StudyUser, on_delete=models.CASCADE, primary_key=True, verbose_name='用户属性ID') study_level = models.IntegerField(verbose_name='学习级别: 1-小学,2-初中,3-高中,4-本科,5-硕士,6-博士,7-博士后') intelligence = models.IntegerField(verbose_name='智力') memory = models.IntegerField(verbose_name='记忆力') diligence = models.IntegerField(verbose_name='勤奋力') physical_fitness = models.IntegerField(verbose_name='体能') total_points = models.IntegerField(verbose_name='总积分') other_subjects = models.CharField(max_length=100, verbose_name='其他学科属性') notes = models.TextField(verbose_name='备注') update_time = models.DateTimeField(verbose_name='更新时间') class Meta: verbose_name = '学生用户属性表' verbose_name_plural = '学生用户属性表' # 用于模型的数据库表的名称 db_table = "study_user_attributes" def __str__(self): return str(self.user)
2,编辑urls配置文件:
./mysite/study_system/urls.py
urlpatterns = [ # 登录首页url path('', views.index, name='index'), path('login/', LoginView.as_view(), name='login'), # 登录主页url path('home/', views.home, name='home'), # 注册url path('register/', views.register, name='register'), ]
3,编辑视图文件:
./mysite/study_system/views.py
def register(request): ''' @方法名称: ajax请求, 表单视图,注册用户 @作 者: PandaCode辉 @weixin公众号: PandaCode辉 @创建时间: 2023-10-10 ''' # 初始化响应容器 rsp_dict = {"result": "error", "errorMsg": "系统错误"} # 是否ajax请求 if request.is_ajax(): try: rest = request.POST # 角色:1: 系统管理员;2: 辅导员;3: 学生;4-自导自学 role = rest['role'] username = rest['username'] password = rest['password'] email = rest['email'] # print('email : '+str(email)) # 根据邮箱查询校验账号是否存在 exists = StudyUser.is_email_exists(email) # print('exists : '+str(exists)) if exists: # 用户注册校验失败,显示错误信息 rsp_dict["errorMsg"] = "该邮箱已经存在注册用户,不能重复注册." # 错误返回json数据格式 return JsonResponse(rsp_dict) # 手机号初始为空 phone_num = "" # 辅导员用户ID,学生用户必输 parent_id = 0 # 今天 # UTC格式当前时区时间 t = time.localtime() work_date = time.strftime("%Y-%m-%d %H:%M:%S", t) print('当前日期时间:' + str(work_date)) # 3: 学生,需要关联对应辅导员账号 if role == '3': # 根据辅导员邮箱查询辅导员的用户信息 parent_email = rest['parent_email'] parent_user = StudyUser.get_user_by_email(parent_email) # print('parent_user : '+str(parent_user)) if parent_user: # 找到了与邮箱匹配的用户,访问用户的属性,辅导员用户ID parent_id = parent_user.user_id else: # 没有找到与邮箱匹配的用户,执行相应的逻辑 # 用户注册校验失败,显示错误信息 rsp_dict["errorMsg"] = "没有找到与辅导员邮箱匹配的用户,注册失败." # 错误返回json数据格式 return JsonResponse(rsp_dict) # 创建用户对象并保存到数据库 user = StudyUser(role=role, username=username, password=password, email=email, phone_num=phone_num, parent_id=parent_id, created_time=work_date, update_time=work_date) # 保存用户表数据 user.save() # 3: 学生;4-自导自学'。增加属性表数据 if role in ('3', '4'): # 创建用户对象并保存到数据库,首次注册,所有属性值初始化为0或空 userAttribute = StudyUserAttribute(user=user, study_level=1, intelligence=0, memory=0, diligence=0, physical_fitness=0, total_points=0, other_subjects="", notes="", update_time=work_date) # 保存属性表数据 userAttribute.save() # 注册成功 rsp_dict["result"] = "success" rsp_dict["errorMsg"] = "注册成功,请登录." # 成功返回json数据格式 return JsonResponse(rsp_dict) except Exception as e: rsp_dict["errorMsg"] = "注册用户失败." # 错误返回json数据格式 return JsonResponse(rsp_dict) else: # 跳转到注册页面 return render(request, "study_system/register.html", rsp_dict)
4,编辑页面模板代码:
4.1. 用户注册页面
./mysite/study_system/templates/study_system/register.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>study system</title> <link rel="stylesheet" href="/static/study_system/bootstrap3/css/bootstrap.min.css"> <script type="text/javascript" src="/static/study_system/jquery1.3.3/jquery.min.js"></script> <style> .container { max-width: 400px; margin: 0 auto; padding-top: 100px; } </style> <script type="text/javascript"> /* 自动载入 */ $(function () { // 清空输入栏 clean_input(); }); // 清空输入栏 function clean_input() { $("#username").val(""); $("#password").val(""); $("#email").val(""); $("#parent_email").val(""); } // 学习模式切换不同角色选择 function change_study_type() { var study_type = $("select[name='study_type']").val(); {#alert(study_type);#} var optionHtml = ""; if (study_type == '1') { optionHtml += "<option value='4'>自导自学</option>"; } else { optionHtml += "<option value='2'>辅导员</option>"; optionHtml += "<option value='3'>学生</option>"; } {## 清空子元素#} $("select[name='role']").empty(); // 添加到class=中 $("select[name='role']").append(optionHtml); // 角色切换,显示,隐藏关联邮箱输入框 change_role(); // 清空输入栏 clean_input(); } // 角色切换,显示,隐藏关联邮箱输入框 function change_role() { var role = $("select[name='role']").val(); {#alert(role);#} if (role === '3') { $('#parent-email-group').show(); } else { $('#parent-email-group').hide(); } } //验证,用户名 function check_username() { if ($("#username").val() == "") { alert("用户名,不能为空"); return false; } return true; } //验证,密码 function check_password() { if ($("#password").val() == "") { alert("密码,不能为空"); return false; } return true; } //验证,邮箱 function check_email() { if ($("#email").val() == "") { alert("邮箱,不能为空"); return false; } return true; } //提交表单 function submitRegister() { if (check_username() && check_password() && check_email()) { var role = $("#role").val(); var username = $("#username").val(); var password = $("#password").val(); var email = $("#email").val(); var parent_email = ""; if (role == "3") { parent_email = $("#parent_email").val(); } //alert("parent_email:" + parent_email); // 1,获取csrfmiddlewaretoken的input标签value属性对应的值 {#var token = $('[name="csrfmiddlewaretoken"]').val();#} // 2,直接就能得到 csrfmiddlewaretoken 的input标签value属性的值 var csrf_token = '{{ csrf_token }}'; $.post("/study_system/register/", { 'role': role, 'username': username, 'password': password, 'email': email, 'parent_email': parent_email, // 将token值放到请求数据部分,token的键必须是 csrfmiddlewaretoken 'csrfmiddlewaretoken': csrf_token, }, function (data) { if ("success" == data.result) { alert("注册成功"); // 注册成功,去登录页面 window.location.href = "/study_system/login/"; } else { alert("注册失败:" + data.errorMsg); } }); } } </script> </head> <body> <div class="container"> <h2 class="text-center">注册用户</h2> <form method="post" action="{% url 'study_system:register' %}"> {# 在Django中提交数据到后端服务的时候,为了安全,要使用CSRF(跨站请求伪造)。#} {% csrf_token %} <div class="form-group"> <label for="study_type">学习模式</label> <select class="form-control" id="study_type" name="study_type" onchange="change_study_type()"> <option value="1" selected="selected">单人模式</option> <option value="2">双人模式</option> </select> </div> <div class="form-group"> <label for="role">角色类型</label> <select class="form-control" id="role" name="role" onchange="change_role()"> {# <option value="2">辅导员</option>#} {# <option value="3">学生</option>#} <option value="4" selected="selected">自导自学</option> </select> </div> <div class="form-group"> <label for="username">用户名</label> <input type="text" class="form-control" id="username" name="username"> </div> <div class="form-group"> <label for="password">密码</label> <input type="password" class="form-control" id="password" name="password"> </div> <div class="form-group"> <label for="email">邮箱</label> <input type="email" class="form-control" id="email" name="email"> </div> <div id="parent-email-group" class="form-group" style="display: none;"> <label for="parent_email">关联辅导员邮箱</label> <input type="email" class="form-control" id="parent_email" name="parent_email"> </div> <div class="form-group"> <button type="button" onclick="submitRegister()" class="form-control btn-primary">注册账户</button> </div> <div class="form-group"> <button type="reset" class="form-control btn-primary" onclick="clearErrorMessage()">重置</button> </div> <div class="form-group"> <a href="{% url 'study_system:login' %}" class="form-control btn-link text-right">登录账户</a> </div> </form> </div> </body> </html>
第二步:运行测试-用户注册功能
1,双人模式
1.1,先注册一个辅导员用户
作为老师/辅导员/家长等角色,用来发布任务,配置定时任务,维护兑换物品,发放奖励物品等,监督管理学生作用,因为没有真正的智能系统,需要人工监管学生的行为规范,督促学生完成学习任务,一个辅导员可以关联多个学生用户。
1.2,再注册一个学生用户
作为学生角色,用来接收对应辅导员和系统发布的任务,完成任务,获取积分,兑换物品,扣除积分,拥有属性表值等,学生用户必须绑定关联一个辅导员用户。
1,单人模式
自己发布任务给自己,自己学习完成任务,自己维护兑换物品,自己兑换奖励物品,没有其他人监督管理,该模式需要较强的自学能力。
-------------------------------------------------end -------------------------------------------------