通用的Django注册功能模块实现方法


Posted in Python onFebruary 05, 2021

注册功能实现

  • forms组件进行表单验证;
  • 用户头像前端实时展示;
  • ajax发送post请求;

应用forms组件实现用户输入信息的校验。首先在app目录下创建一个myform.py的文件。

如果你的项目至始至终只用到一个forms组件那么你可以直接建一个py文件书写即可。

但是如果你的项目需要使用多个forms组件,那么你可以创建一个myforms文件夹在文件夹内,根据forms组件功能的不同创建不同的py文件。

  • regform.py
  • loginform.py
  • userform.py
  • orderform.py

......

# 书写针对用户表的forms主键代码
from django import forms
from app01 import models

class MyRegForm(forms.Form):
  username = forms.CharField(label='用户名',min_length=3,max_length=8,
                error_messages={
                  'required':'用户名不能为空',
                  'min_length':'用户名最少3位',
                  'max_length':'用户名最大8位'
                },
                # 还需要让标签有Bootstrap样式
                widget=forms.widgets.TextInput(attrs={'class':'form-control'})
                )
  password = forms.CharField(label='密码',min_length=3,max_length=8,
                error_messages={
                  'required':'密码不能为空',
                  'min_length':'密码最少3位',
                  'max_length':'密码最大8位'
                },
                # 还需要让标签有Bootstrap样式
                widget=forms.widgets.PasswordInput(attrs={'class':'form-control'})
                )
  confirm_password = forms.CharField(label='确认密码',min_length=3,max_length=8,
                    error_messages={
                    'required':'确认密码不能为空',
                    'min_length':'确认密码最少3位',
                    'max_length':'确认密码最大8位'
                  },
                  # 还需要让标签有Bootstrap样式
                  widget=forms.widgets.PasswordInput(attrs={'class':'form-control'})
                  )
  email = forms.EmailField(label='邮箱',
               error_messages={
                 'required': '邮箱不能为空',
                 'invalid':'邮箱格式不正确',
               },
               widget=forms.widgets.EmailInput(attrs={'class':'form-control'})
               )

  # 钩子函数
  # 局部钩子:校验用户名是否已存在
  def clean_username(self):
    username = self.cleaned_data.get('username')
    # 去数据库中校验
    is_exist = models.UserInfo.objects.filter(username=username)
    if is_exist:
      # 提示信息
      self.add_error('username','用户名已存在')
    return username

  # 全局钩子:校验两次密码是否一致
  def clean(self):
    password = self.cleaned_data.get('password')
    confirm_password = self.cleaned_data.get('confirm_password')
    if not password == confirm_password:
      self.add_error('confirm_password','两次密码不一致')
    return self.cleaned_data

然后在urls.py中配置注册页的路由信息。

from django.contrib import admin
from django.urls import path
from app01 import views

urlpatterns = [
  path('admin/', admin.site.urls),
  path('register/',views.register,name='reg'),
]

在视图函数views.py中编写forms组件检验、ajax发送的post请求获取数据、调用django orm功能存储数据、将后端的处理结果返回给前端进行校验。

from app01.myforms import MyRegForm
from app01 import models
from django.http import JsonResponse
# Create your views here.

def register(request):
  form_obj = MyRegForm()
  if request.method == 'POST':
    # 定义返回给前端的js数据结果
    back_dic = {"code": 1000, 'msg': ''}
    # 校验数据是否合法
    form_obj = MyRegForm(request.POST)
    # 判断数据是否合法
    if form_obj.is_valid():
      # form_obj.cleaned_data:{'username': 'zhangsan', 'password': '123456', 'confirm_password': '123456', 'email': '123@qq.com'}
      # 将校验通过的数据字典赋值给一个变量
      clean_data = form_obj.cleaned_data 
      # 将字典里面的confirm_password键值对删除
      clean_data.pop('confirm_password') # {'username': 'zhangsan', 'password': '123456', 'email': '123@qq.com'}
      
      # 注意用户头像是一个图片的文件,request.POST中只有键值对的数据
      file_obj = request.FILES.get('avatar')
      """
      	针对用户头像一定要判断是否传值,不能直接添加到字典里面去
      	否则file_obj=None,会将数据库中默认的图片路径覆盖。
      """
      if file_obj:
        # 向字典数据clean_data中增加一个图片头像的字段
        clean_data['avatar'] = file_obj
      # 操作数据库保存数据
      models.UserInfo.objects.create_user(**clean_data)
      # 注册成功则跳转到登录页面
      back_dic['url'] = '/login/'
    else:
      back_dic['code'] = 2000 # 校验存在错误
      back_dic['msg'] = form_obj.errors
    # 将字典类型的数据封装成json返回到前端
    return JsonResponse(back_dic)
  return render(request,'register.html',locals())

前端的注册页面:register.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <!-- Bootstrap -->
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" rel="external nofollow" rel="stylesheet">
  <script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js">
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"></script>
  <title>用户注册</title>
</head>
<body>
<div class="container-fluid">
  <div class="row">
    <div class="col-md-8 col-md-offset-2">
      <h1 class="text-center">注册</h1>
      <form id="myform"> <!--这里我们不用form表单提交数据 知识单纯的用一下form标签而已-->
        {% csrf_token %}
        {% for form in form_obj %}
          <div class="form-group">
            <label for="{{ form.auto_id }}">{{ form.label }}</label>
            {{ form }}
            <span style="color: red" class="pull-right"></span>
          </div>
        {% endfor %}
        
        <div class="form-group">
          <label for="myfile">头像
            {% load static %}
            <img src="{% static 'img/default.jpg' %}" id='myimg' alt="" width="100" style="margin-left: 10px">
          </label>
          <input type="file" id="myfile" name="avatar" style="display: none" >
        </div>

        <input type="button" class="btn btn-primary pull-right" value="注册" id="id_commit">
      </form>
    </div>
  </div>
</div>
</body>
</html>

【重难点】在于书写JS处理逻辑:包括了图片上传加载、ajax发送的post请求以及后端注册结果的信息处理。

<script>
  $("#myfile").change(function () {
    // 文件阅读器对象
    // 1 先生成一个文件阅读器对象
    let myFileReaderObj = new FileReader();
    // 2 获取用户上传的头像文件
    let fileObj = $(this)[0].files[0];
    // 3 将文件对象交给阅读器对象读取
    myFileReaderObj.readAsDataURL(fileObj) // 异步操作 IO操作
    // 4 利用文件阅读器将文件展示到前端页面 修改src属性
    // 等待文件阅读器加载完毕之后再执行
    myFileReaderObj.onload = function(){
       $('#myimg').attr('src',myFileReaderObj.result)
    }
  })

  $('#id_commit').click(function () {
    // 发送ajax请求   我们发送的数据中即包含普通的键值也包含文件
    let formDataObj = new FormData();
    // 1.添加普通的键值对
    {#console.log($('#myform').serializeArray()) // [{},{},{},{},{}] 只包含普通键值对#}
    $.each($('#myform').serializeArray(),function (index,obj) {
      {#console.log(index,obj)#} // obj = {}
      formDataObj.append(obj.name,obj.value)
    });
    // 2.添加文件数据
    formDataObj.append('avatar',$('#myfile')[0].files[0]);

    // 3.发送ajax请求
    $.ajax({
      url:"",
      type:'post',
      data:formDataObj,

      // 需要指定两个关键性的参数
      contentType:false,
      processData:false,

      success:function (args) {
        if (args.code==1000){
          // 跳转到登陆页面
          //window.location.href = args.url
        }else{
          // 如何将对应的错误提示展示到对应的input框下面
          // forms组件渲染的标签的id值都是 id_字段名
          $.each(args.msg,function (index,obj) {
            {#console.log(index,obj) // username    ["用户名不能为空"]#}
            let targetId = '#id_' + index;
            $(targetId).next().text(obj[0]).parent().addClass('has-error')
          })
        }
      }
    })
  })
  // 给所有的input框绑定获取焦点事件
  $('input').focus(function () {
    // 将input下面的span标签和input外面的div标签修改内容及属性
    $(this).next().text('').parent().removeClass('has-error')
  })
</script>

效果如下:

通用的Django注册功能模块实现方法

以上就是通用的Django注册功能模块实现步骤的详细内容,更多关于Django注册功能模块实现的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
python中类和实例如何绑定属性与方法示例详解
Aug 18 Python
python学习笔记--将python源文件打包成exe文件(pyinstaller)
May 26 Python
python TKinter获取文本框内容的方法
Oct 11 Python
python2与python3中关于对NaN类型数据的判断和转换方法
Oct 30 Python
python3 enum模块的应用实例详解
Aug 12 Python
python通过txt文件批量安装依赖包的实现步骤
Aug 13 Python
Python笔试面试题小结
Sep 07 Python
python 计算积分图和haar特征的实例代码
Nov 20 Python
pymysql的简单封装代码实例
Jan 08 Python
python 实现socket服务端并发的四种方式
Dec 14 Python
python实现Thrift服务端的方法
Apr 20 Python
python百行代码实现汉服圈图片爬取
Nov 23 Python
Pycharm 设置默认解释器路径和编码格式的操作
Feb 05 #Python
ASP.NET Core中的配置详解
Feb 05 #Python
pycharm 的Structure界面设置操作
Feb 05 #Python
Python实现疫情地图可视化
Feb 05 #Python
pycharm 实现调试窗口恢复
Feb 05 #Python
Biblibili视频投稿接口分析并以Python实现自动投稿功能
Feb 05 #Python
Pycharm 跳转回之前所在页面的操作
Feb 05 #Python
You might like
PHP教程 变量定义
2009/10/23 PHP
ThinkPHP中公共函数路径和配置项路径的映射分析
2014/11/22 PHP
php集成动态口令认证
2016/07/21 PHP
PHP单例模式与工厂模式详解
2017/08/29 PHP
laravel在中间件内生成参数并且传递到控制器中的2种姿势
2019/10/15 PHP
再谈IE中Flash控件的自动激活 ObjectWrap
2007/03/09 Javascript
JavaScript中__proto__与prototype的关系深入理解
2012/12/04 Javascript
Extjs单独定义各组件的实例代码
2013/06/25 Javascript
js阻止默认事件与js阻止事件冒泡示例分享 js阻止冒泡事件
2014/01/27 Javascript
javascript 实现子父窗体互相传值的简单实例
2014/02/17 Javascript
在Node.js中实现文件复制的方法和实例
2014/06/05 Javascript
js单独获取一个checkbox看其是否被选中
2014/09/22 Javascript
基于replaceChild制作简单的吞噬特效
2015/09/21 Javascript
深入浅析NodeJs并发异步的回调处理
2015/12/21 NodeJs
javascript汉字拼音互转的简单实例
2016/10/09 Javascript
JS验证码实现代码
2017/09/14 Javascript
javascript  删除select中的所有option的实例
2017/09/17 Javascript
Javascript中JSON数据分组优化实践及JS操作JSON总结
2017/12/22 Javascript
JavaScript中使用import 和require打包后实现原理分析
2018/03/07 Javascript
微信小程序实现预览图片功能
2020/10/22 Javascript
js获取对象,数组所有属性键值(key)和对应值(value)的方法示例
2019/06/19 Javascript
详解ECMAScript2019/ES10新属性
2019/12/06 Javascript
js实现列表向上无限滚动
2020/01/13 Javascript
python实现绘制树枝简单示例
2014/07/24 Python
实例讲解python中的序列化知识点
2018/10/08 Python
python tkinter组件使用详解
2019/09/16 Python
美国大码时尚女装购物网站:ELOQUII
2017/12/28 全球购物
通信工程专业女生个人求职信
2013/09/21 职场文书
内科护士实习自我鉴定
2013/10/17 职场文书
年度考核自我鉴定
2013/11/09 职场文书
研发工程师的岗位职责
2013/11/18 职场文书
技能比赛获奖感言
2014/02/14 职场文书
创业计划书之个人工作室
2019/08/22 职场文书
详解Java实践之适配器模式
2021/06/18 Java/Android
浅谈 JavaScript 沙箱Sandbox
2021/11/02 Javascript
关于 Python json中load和loads区别
2021/11/07 Python