路由层

from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^register/', views.register, name='register'),
    url(r'^login/', views.login, name='login'),
    url(r'^get_code/', views.get_code, name='get_code'),
    url(r'^home/', views.home, name='home'),
    url(r'^cancellation/', views.cancellation, name='cancellation'),
    url(r'^change_password/', views.change_password, name='change_password'),
]

登陆

html页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css">
    <script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container-fluid">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <h2 class="text-center">登陆</h2>
            <hr>
            <div class="form-group">
                {% csrf_token %}
                <label for="id_username">用户名</label>
                <input type="text" name="username" id="id_username" class="form-control">
            </div>
            <div class="form-group">
                <label for="id_password">密码</label>
                <input type="password" name="password" id="id_password" class="form-control">
            </div>
            <div class="form-group">
                <label for="is_code">验证码</label>
                <div class="row">
                    <div class="col-md-6">
                        <input type="text" name="code" id="is_code" class="form-control">
                    </div>
                    <div class="col-md-6">
                        <img src="{% url 'get_code' %}" alt="" width="280" height="35" id="id_img">
                    </div>
                </div>
            </div>
            <div class="form-group">
                <input type="button" value="登陆" class="btn btn-primary" id="id_button">
                <span class="errors" style="color: red"></span>
            </div>

        </div>
    </div>
</div>
<script>
    $('#id_img').click(function () {
        let code = $(this).attr('src');
        $(this).attr('src', code += "?");
    });
    $('#id_button').click(function () {
        $.ajax({
            url: '',
            type: 'post',
            data: {
                'username': $('#id_username').val(),
                'password': $("#id_password").val(),
                'code': $('#is_code').val(),
                'csrfmiddlewaretoken': "{{ csrf_token }}"
            },
            success: function (data) {
                if (data.code == 100) {
                    location.href = data.url

                } else {
                    $('.errors').text(data.msg);
                    $('input').parent().addClass('has-error')
                }
            }

        })
    });
    $('input').focus(function () {
        $(this).parent().removeClass('has-error')
    })

</script>
</body>
</html>

views视图函数

def login(request):
    response_msg = {'code': 100, 'msg': ''}
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        code = request.POST.get('code')
        # 先判断用户有没有输入完整的用户信息 如果没有直接返回错误信息
        if not username or not password or not code:
            response_msg['code'] = 104
            response_msg['msg'] = '请完善信息'
            return JsonResponse(response_msg)
        #         1.校验步骤比对验证码是否正确
        if request.session.get("code").upper() == code.upper():
            # 统一转大写或者小写进行比对,实现忽略大小写
            # 2。校验用户名密码
            user = models.UserInfo.objects.filter(username=username)
            if user:
                user_obj = auth.authenticate(username=username, password=password)
                if user_obj:
                    auth.login(request, user_obj)
                    response_msg['msg'] = '登陆成功'
                    response_msg['url'] = '/home/'
                else:
                    response_msg['code'] = 101
                    response_msg['msg'] = '密码错误'
            else:
                response_msg['code'] = 102
                response_msg['msg'] = '用户名不存在'
        else:
            response_msg['code'] = 103
            response_msg['msg'] = '验证码错误'
        return JsonResponse(response_msg)
    return render(request, 'login.html')

生成随机动态验证码

def get_random():
    return random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)

# 获取验证码
def get_code(request):
    # 推导步骤1:直接传本地的图片二进制数据
    # with open('static/img/default.jpg', 'rb') as f:
    #     data = f.read()
    # return HttpResponse(data)

    # 推导步骤2:动态生成图片传递到前端
    # 调用Image生成图片对象
    # img = Image.new('RGB', (280, 35), (45, 45, 45))  # 第三个参数可以传颜色英文,也支持,(255,255,255)颜色参数
    # # 保存文件对象
    # with open('demo.png', 'wb') as f:
    #     img.save(f, 'png')
    # # 读取文件
    # with open('demo.png', 'rb') as f:
    #     data = f.read()
    # return HttpResponse(data)
    # 步骤3:找一个更方便的地方存取文件,图片颜色动态变化
    # img = Image.new('RGB', (280, 35), get_random())  # 定义random函数解决图片颜色动态变化问题
    # io_obj = BytesIO()  # 生成一个BytesIO对象,把它看作文件句柄
    # img.save(io_obj, 'png')  # 将文件对象存入io_obj中
    # return HttpResponse(io_obj.getvalue())  # 取出图片二进制数据

    # 推导步骤4:动态生成图片并且图片上附有文字验证码
    img = Image.new('RGB', (280, 35), (get_random()))
    img_draw = ImageDraw.Draw(img)  # 生成一个画笔,可以在img图片上为所欲为
    img_font = ImageFont.truetype('static/font/2.ttf', 35)  # 定义字体样式
    # 写验证码 数字+小写字母+大写字母
    code = ''
    for i in range(5):
        random_num = str(random.randrange(0, 9))
        random_upper = str(chr(random.randint(65, 90)))
        random_lower = str(chr(random.randint(97, 122)))
        #         随机选择一个字符写入图片上
        random_code = random.choice([random_num, random_upper, random_lower])
        img_draw.text((45 + i * 45, -10), random_code, get_random(), img_font)
        code += random_code
    # print(code)
    io_obj = BytesIO()
    # 将生成好的带有验证码的图片存入io_obj
    img.save(io_obj, 'png')
    print(code)
    # 将验证码记录下来以便后续比对,存入session以便后续比对
    request.session['code'] = code
    return HttpResponse(io_obj.getvalue())

注册

自定义form组件

class RegForm(forms.Form):
    username = forms.CharField(max_length=8, min_length=3, label='用户名', error_messages={
        'max_length': '用户名最长8位',
        'min_length': '用户名最少3位',
        'required': '用户名不能为空',
    }, widget=forms.TextInput(attrs={'class': 'form-control'}))
    password = forms.CharField(max_length=8, min_length=3, label='密码', error_messages={
        'max_length': '密码最长8位',
        'min_length': '密码最少3位',
        'required': '密码不能为空',
    }, widget=forms.PasswordInput(attrs={'class': 'form-control'}))
    confirm_password = forms.CharField(max_length=8, min_length=3, label='确认密码', error_messages={
        'max_length': '确认密码最长8位',
        'min_length': '确认密码最少3位',
        'required': '确认密码不能为空',
    }, widget=forms.PasswordInput(attrs={'class': 'form-control'}))
    email = forms.CharField( label='邮箱', error_messages={
        'invalid': '邮箱格式不正确',
        'required': '密码不能为空',
    }, widget=forms.EmailInput(attrs={'class': 'form-control'}))

    # 局部钩子 校验用户是否已存在
    def clean_username(self):
        username = self.cleaned_data.get('username')
        user = models.UserInfo.objects.filter(username=username)
        if user:
            self.add_error('username', '用户名已存在')
        else:
            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', '两次密码不一致')
        else:
            return self.cleaned_data

html页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css">
    <script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container-fluid">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <h2 class="text-center">注册</h2>
            <hr>
            <form id="my_form">
                {% csrf_token %}
                {% for foo in form_obj %}
                    <div class="form-group">
                        <label for="{{ foo.auto_id }}">{{ foo.label }}</label>
                        {{ foo }}
                        <span class="errors pull-right" style="color: red"></span>
                    </div>
                {% endfor %}
                <div class="form-group">
                    <label for="id_my_file">头像
                        <img src="/static/img/default.jpg" alt="" width="80" style="margin-left: 20px" id="id_img">
                    </label>
                    <input type="file" name="my_file" id="id_my_file" style="display: none">
                </div>
                <input type="button" class="btn btn-primary pull-right" id="id_button" value="提交">
            </form>
        </div>
    </div>
</div>
<script>
    $('#id_my_file').change(function () {
        //获取当前用户上传到的文件对象
        let my_file_obj = $(this)[0].files[0];
        //需要用文件阅读器这个内置对象
        let fileReader = new FileReader();
        //将文件对象丢给文件阅读器
        fileReader.readAsDataURL(my_file_obj);
        //将文件对象放入img标签的src属性中
        //当文件对象全部加载完毕再渲染
        fileReader.onload = function () {
            $('#id_img').attr('src', fileReader.result);
        }
    });
    $('#id_button').click(function () {
        let formDate = new FormData();
        //自动获取form表单中所有input框键值对
        $.each($('#my_form').serializeArray(), function (index, obj) {
            formDate.append(obj.name, obj.value)//自动添加了普通的键值对,文件对象需要你手动添加
        });
        //手动添加文件对象
        formDate.append('my_file', $('#id_my_file')[0].files[0]);
        $.ajax({
            url: '',
            type: 'post',
            data: formDate,
            //用formData传数据的时候需要指定两个参数
            processData: false,
            contentType: false,
            success: function (data) {
                if (data.code == 100) {
                    location.href = data.url
                } else {
                    $.each(data.msg, function (index, obj) {
                        //手动拼接处forms组件渲染的input的id值
                        let targetId = '#id_' + index;
                        $(targetId).next().html(obj[0]).parent().addClass('has-error')
                    })
                }
            }

        })
    });
    $('input').focus(function () {
        $(this).next().html('').parent().removeClass('has-error')
    })
</script>
</body>
</html>

views视图函数

def register(request):
    response_msg = {'code': 100, 'msg': ''}
    form_obj = myforms.RegForm()
    if request.method == "POST":
        form_obj = myforms.RegForm(request.POST)
        if form_obj.is_valid():
            clean_data = form_obj.cleaned_data
            #         删除确认密码的键值对
            clean_data.pop('confirm_password')
            #         获取用户上传的头像
            user_avatar = request.FILES.get('my_file')

            if user_avatar:
                clean_data['avatar'] = user_avatar
            models.UserInfo.objects.create_user(**clean_data)
            response_msg['msg'] = '注册成功'
            response_msg['url'] = '/login/'
        else:
            response_msg['code'] = 101
            response_msg['msg'] = form_obj.errors
        return JsonResponse(response_msg)
    return render(request, 'register.html', locals())

主页面

html页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>博客园主页</title>
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css">
    <script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<nav class="navbar navbar-inverse">
    <div class="container-fluid">
        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
                    data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="#">博客园</a>
        </div>

        <!-- Collect the nav links, forms, and other content for toggling -->
        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
            <ul class="nav navbar-nav">
                <li><a href="#">文章 </a></li>
                <li><a href="#">随笔</a></li>

            </ul>
            {% if request.user.is_authenticated %}
                <ul class="nav navbar-nav navbar-right">
                    <li><a href="#">{{ request.user.username }}</a></li>
                    <li class="dropdown">
                        <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
                           aria-expanded="false">更多操作 <span class="caret"></span></a>
                        <ul class="dropdown-menu">
                            <li><a href="{% url 'change_password' %}">修改密码</a></li>
                            <li><a href="#">修改头像</a></li>
                            <li role="separator" class="divider"></li>
                            <li><a href="{% url 'cancellation' %}">注销</a></li>
                        </ul>
                    </li>
                </ul>
            {% else %}
                <ul class="nav navbar-nav navbar-right">
                    <li><a href="{% url 'login' %}">登陆</a></li>
                    <li><a href="{% url 'register' %}">注册</a></li>
                </ul>
            {% endif %}

        </div><!-- /.navbar-collapse -->
    </div><!-- /.container-fluid -->
</nav>
<div class='container-fluid'>
    <div class="row">
        <div class="col-md-2">
            <div class="panel panel-info">
                <div class="panel-heading">
                    <h3 class="panel-title">Panel title</h3>
                </div>
                <div class="panel-body">
                    Panel content
                </div>
            </div>
        </div>
        <div class="col-md-8"></div>
        <div class="col-md-2">
            <div class="panel panel-info">
                <div class="panel-heading">
                    <h3 class="panel-title">Panel title</h3>
                </div>
                <div class="panel-body">
                    Panel content
                </div>
            </div>
        </div>
    </div>
</div>
</body>
</html>

views视图函数

def home(request):
    return render(request, 'homepage.html')

修改密码

html页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css">
    <script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container-fluid">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <h2 class="text-center">修改密码</h2>
            <hr>
            <div class="form-group">
                {% csrf_token %}
                <label >用户名</label>
                <input type="text" name="username" value="{{ request.user.username }}" disabled class="form-control">
            </div>
            <div class="form-group">
                <label for="old_password">原密码</label>
                <input type="password" name="old_password" id="old_password" class="form-control">
            </div>
            <div class="form-group">
                <label for="new_password">新密码</label>
                <input type="password" name="new_password" id="new_password" class="form-control">
            </div>
            <div class="form-group">
                <label for="confirm_password">确认密码</label>
                <input type="password" name="confirm_password" id="confirm_password" class="form-control">
            </div>
            <div class="form-group">
                <input type="button" value="确定" class="btn btn-primary" id="id_button">
                <span class="errors" style="color: red"></span>
            </div>

        </div>
    </div>
</div>
<script>
    $('#id_button').click(function () {
        $.ajax({
            url:'',
            type:'post',
            data:{
                'old_password':$("#old_password").val(),
                'new_password':$('#new_password').val(),
                'confirm_password':$('#confirm_password').val(),
                'csrfmiddlewaretoken': "{{ csrf_token }}"
            },
            success:function (data) {
                if (data.code==100){
                    location.href= data.url
                } else{
                    $('.errors').text(data.msg);
                    $('input').parent().addClass('has-error')
                }
            }
        })
    })

</script>
</body>
</html>

views视图函数

def change_password(request):
    response_msg = {'code': 100, 'msg': ''}
    user = request.user
    if request.method == 'POST':
        old_password = request.POST.get('old_password')
        new_password = request.POST.get('new_password')
        confirm_password = request.POST.get('confirm_password')
        if not old_password or not new_password or not confirm_password:
            response_msg['code'] = 101
            response_msg['msg'] = '请完善信息'
            return JsonResponse(response_msg)
        if user.check_password(old_password):
            if new_password == confirm_password:
                user.set_password(confirm_password)
                user.save()
                response_msg['url'] = '/login/'
                response_msg['msg'] = '修改成功'
            else:
                response_msg['code'] = 102
                response_msg['msg'] = '两次密码不一致'
        else:
            response_msg['code'] = 103
            response_msg['msg'] = '输入的原密码错误'
        return JsonResponse(response_msg)
    return render(request, 'change_password.html')

注销

views视图函数

def cancellation(request):
    auth.logout(request)
    return redirect(reverse('home'))

Django 登陆注册实现的更多相关文章

  1. git冲突解决、线上分支合并、luffy项目后台登陆注册页面分析引入

    今日内容概要 git冲突解决 线上分支合并 登陆注册页面(引入) 手机号是否存在接口 腾讯云短信申请 内容详细 1.git冲突解决 1.1 多人在同一分支开发,出现冲突 # 先将前端项目也做上传到 g ...

  2. Android通过Http连接MySQL 实现登陆/注册(数据库+服务器+客户端)

    写在最前: 在实际开发中,相信每个项目都会有用户登陆注册功能,这个实现的方法很多,下面是我实现的方法,供大家交流. 新人发帖,万分紧张,怎么样才能装作一副经常发帖的样子不被别人看出来呢-,- ? 好了 ...

  3. java 24 - 11 GUI之制作登陆注册页面

    简单说说,懒得发了... 步骤: A:首先写出登陆注册需要用到类以及代码(IO流) B:然后创建登陆窗口和注册窗口 C:各个监听事件: a:登录窗口 1.重置:把2个文本框的内容全部清空 2.注册:关 ...

  4. PHP数据库登陆注册简单做法

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. javaweb 登陆注册页面

    视图的数据修改,表中也修改引用工具类用<%@ page import=""%> <%@ page import="java.util.Date" ...

  6. 用户登陆注册【JDBC版】

    前言 在讲解Web开发模式的时候,曾经写过XML版的用户登陆注册案例!现在在原有的项目上,使用数据库版来完成用户的登陆注册!如果不了解的朋友,可以看看我Web开发模式的博文! 本来使用的是XML文件作 ...

  7. 用ajax的同步请求解决登陆注册需要根据服务器返回数据判断是否能提交的问题

    最近在写www.doubilaile.com的登陆注册.需要用ajax请求服务器判断用户名是否存在,用户名和密码是否匹配,进而提交数据.碰到的问题是异步请求都能成功返回数据,但是该数据不能作为紧接着的 ...

  8. tkinter 创建登陆注册界面

    import tkinter as tk from tkinter import messagebox #设置窗口居中 def window_info(): ws = window.winfo_scr ...

  9. 《java入门第一季》模拟用户登陆注册案例集合版

    需求:校验用户名和密码,登陆成功后玩猜数字小游戏. 在这里先写集合版.后面还有IO版.数据库版. 一.猜数字小游戏类: 猜数字小游戏的代码见博客:http://blog.csdn.net/qq_320 ...

随机推荐

  1. max文件属性设置,

    之前一直都没找到 用到的时候就是用net 弄了.哎.还在开发东西都是在9上面, 这次脚本必须在 max8 上面 逼的我找到了他 getFileAttribute <filename_string ...

  2. 15 Independent Alleles

    Problem Figure 2. The probability of each outcome for the sum of the values on two rolled dice (blac ...

  3. BI失败的原因

    最最重要的, 要有个清晰的目标和范围. 有些客户, 完全脑袋一热开始上BI, 连根本上要BI来解决什么问题都不知道.作为企业的CIO, 首先要知道上BI项目是不是符合企业的战略目标, 是不是能给企业带 ...

  4. MyBatis 插入主键方式和返回主键

    这使用的mysql数据库,下面这种方式(没有给mysql设置自动增长)是插入主键方式: <insert id="insertBook" parameterType=" ...

  5. 安装及运行 RabbitMQ 服务器 (linux) 失败! 安装erlang 失败,无法继续

    文档 http://www.rabbitmq.com/install-rpm.html 安装前置条件 Before installing RabbitMQ, you must install Erla ...

  6. mysql event 入门

    delimiter | CREATE EVENT statistics_event ON SCHEDULE EVERY DAY STARTS CONCAT(CURRENT_DATE(), ' 00:0 ...

  7. Ubuntu的常识使用了解3

    打包与压缩

  8. 23 DesignPatterns学习笔记:C++语言实现 --- 1.4 Builder

    23 DesignPatterns学习笔记:C++语言实现 --- 1.4 Builder 2016-07-21 (www.cnblogs.com/icmzn) 模式理解

  9. [Elixir004]通过环境变量(Environment Variables)来管理config

    在elixir的config中我们有时会使用的到一些不想暴露出来的配置项,常用的作法是如Phoenix #config/prod.exs use Mix.Config ... # Finally im ...

  10. Docker私有仓库Registry实战

    参考: https://www.cnblogs.com/soar1688/p/6828329.html 1. 关于Registry 官方的Docker hub是一个用于管理公共镜像的好地方,我们可以在 ...