通用的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 相关文章推荐
利用soaplib搭建webservice详细步骤和实例代码
Nov 20 Python
Python的Flask框架中配置多个子域名的方法讲解
Jun 07 Python
python实现按任意键继续执行程序
Dec 30 Python
Python2.7读取PDF文件的方法示例
Jul 13 Python
每天迁移MySQL历史数据到历史库Python脚本
Apr 13 Python
Python 查看list中是否含有某元素的方法
Jun 27 Python
python的schedule定时任务模块二次封装方法
Feb 19 Python
Python基础学习之类与实例基本用法与注意事项详解
Jun 17 Python
如何使用django的MTV开发模式返回一个网页
Jul 22 Python
pytorch 模型的train模式与eval模式实例
Feb 20 Python
使用Django xadmin 实现修改时间选择器为不可输入状态
Mar 30 Python
Selenium结合BeautifulSoup4编写简单的python爬虫
Nov 06 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/04/10 PHP
php Ubb代码编辑器函数代码
2012/07/05 PHP
Laravel学习教程之本地化模块
2017/08/18 PHP
启用OPCache提高PHP程序性能的方法
2019/03/21 PHP
使用jquery为table动态添加行的实现代码
2011/03/30 Javascript
jQuery链式操作如何实现以及为什么要用链式操作
2013/01/17 Javascript
jquery插件开发之实现google+圈子选择功能
2014/03/10 Javascript
javascript怎么禁用浏览器后退按钮
2014/03/27 Javascript
一个实用的图片切换支持点击切换和自动轮播
2014/09/09 Javascript
jQuery中children()方法用法实例
2015/01/07 Javascript
JQuery中上下文选择器实现方法
2015/05/18 Javascript
js实现n秒倒计时后才可以点击的效果
2015/12/20 Javascript
AngularJS控制器之间的数据共享及通信详解
2016/08/01 Javascript
用vue和node写的简易购物车实现
2017/04/25 Javascript
最常用的jQuery表单验证(简单)
2017/05/23 jQuery
Vuex入门到上手教程
2018/06/20 Javascript
React 实现拖拽功能的示例代码
2019/01/06 Javascript
JS实现分页导航效果
2020/02/19 Javascript
Python实现二叉堆
2016/02/03 Python
详解python while 函数及while和for的区别
2018/09/07 Python
Python基于opencv调用摄像头获取个人图片的实现方法
2019/02/21 Python
详解python列表生成式和列表生成式器区别
2019/03/27 Python
Python使用pymysql模块操作mysql增删改查实例分析
2019/12/19 Python
Python生成器next方法和send方法区别详解
2020/05/30 Python
Python StringIO及BytesIO包使用方法解析
2020/06/15 Python
html5新特性与用法大全
2018/09/13 HTML / CSS
html5使用canvas实现跟随光标跳动的火焰效果
2014/01/07 HTML / CSS
利用promise及参数解构封装ajax请求的方法
2021/03/24 Javascript
中英文求职信范文
2014/01/27 职场文书
研究生毕业鉴定
2014/01/29 职场文书
教师职称自我鉴定
2014/02/12 职场文书
公司财务会计主管应聘求职信
2014/09/26 职场文书
师范生见习报告范文
2014/11/03 职场文书
会议主持人开场白台词
2015/05/28 职场文书
MySQL优化及索引解析
2022/03/17 MySQL
Redis全局ID生成器的实现
2022/06/05 Redis