学神python全栈学习笔记CMDB系统---第二章 python_cmdb_前端样式

第二章 python_cmdb_前端样式

本节所讲内容:

2.1  基于bootstrip的模态框绘制

2.2  基于 forms的表单定义

2.3  基于JQ的前端校验

2.4  表单提交完成注册

2.5  基于cmdb的ajax表单提交

2.6  基于SB-Admin的图表绘制

我们以用户注册表单为例,用bootstrap+jq实现前端样式

2.1  基于bootstrap的模态框绘制

我们把用户注册做到一个模态框里面,模态框看着很复杂,实际上很有规律。

模态框分为两部分:

扫描二维码关注公众号,回复: 3129943 查看本文章
  1. 模态框触发按钮

前端界面

\XueGodCMDB36\templates\user_index.html:

通过用户注册触发模态框
{% block page-header %}
    <!--模态框触发部分-->
    <!--
        data-toggle 以何种形式展示模态框 modal、popover
        data-target 模态框id
    -->
    <div class="container-fluid">
        <div class="col-md-8">
            用户管理
        </div>
        <div class="col-md-4" style="text-align:right">
            <button class="btn btn-default" data-toggle="modal" data-target="#register_user_modal">用户注册</button>
            <button class="btn btn-default" data-toggle="modal" data-target="#logout_user_modal">用户退出</button>
        </div>
    </div>
    <!--模态框触发部分结束-->
{% endblock %}

被触发的模态框:

{% block content %}
    <!--模态框展示部分-->
    <!--
    tabindex  table 导航的顺序
    role = dialog 指定展示的样式(角色)为模态框
    aria-labelledby = "MyLabel" 获取值
    footer 页脚
    -->
    <div class="modal fade" data-toggle="modal" id="register_user_modal" tabindex="-1" role="dialog"
         aria-labelledby="Mylabel" aria-hidden="true">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
                    <h4 class="modal-title" id="MyLabel">用户注册</h4>
                </div>
                <form method="post" id="register_form" enctype="multipart/form-data">
                    {% csrf_token %}
                    <div class="modal-body">
                        {% for formitem in user_from %}
                            <div class="form-group input-group">
                                <span class="input-group-addon">{{ formitem.label }}</span>
                                {{ formitem }}
                            </div>
                        {% endfor %}
                    </div>

                    <div class="modal-footer">
                        <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
                        <button type="submit" class="btn btn-primary" id="add_user_submit">提交</button>
                    </div>
                </form>
            </div>
        </div>
    </div>
    <!--模态框展示部分结束-->

模态框效果:

 

基于 forms的表单定义

Django给我们提供了一个很棒的类叫做forms

定义forms文件

 代码如下:

\XueGodCMDB36\User\forms.py:

# !/usr/bin/env python
# -*- coding: utf-8 -*-

from django import forms
from django.forms import widgets


class CMDBUserForm(forms.Form):
    name = forms.CharField(
        max_length=6,  # 长度限制的验证优先级高于前端验证,前后端都要验证,且限制规则相同
        min_length=2,
        label='用户账号',
        widget=widgets.TextInput(
            attrs={
                'class': 'form-control',
                'required': '',
                'minlength': 2,
                'maxlength': 6,
            }
        ),
        error_messages={
            'max_length':'用户名最大6位',
            'min_length':'用户名最小2位',
            'required':'用户名不能为空'
        }
    )
    password = forms.CharField(
        max_length=6,
        min_length=2,
        label='用户密码',
        widget=widgets.PasswordInput(
            attrs={
                'class': 'form-control',
                'required': '',
                'minlength': 2,
                'maxlength': 6,
            }
        )
    )
    nickname = forms.CharField(
        max_length=6,
        min_length=2,
        label='用户姓名',
        widget=widgets.TextInput(
            attrs={
                'class': 'form-control',
                'required': '',
                'minlength': 2,
                'maxlength': 6,
            }
        )
    )
    phone = forms.CharField(
        max_length=11,
        min_length=11,
        label='用户电话',
        widget=widgets.TextInput(
            attrs={
                'class': 'form-control',
                'required': '',
                'minlength': 11,
                'maxlength': 11,
            }
        )
    )
    email = forms.EmailField(
        label='用户邮箱',
        widget=widgets.EmailInput(
            attrs={
                'class': 'form-control',
                'required': '',
            }
        )
    )
    photo = forms.ImageField(
        label='用户照片',
        allow_empty_file=True,
        widget=widgets.FileInput(
            attrs={
                'id': 'logo_file',
                'class': 'file-input-new btn btn-primary btn-file',
                'style': " margin: auto;",
                'required': '',
            }
        )
    )

视图加载,前端渲染

修改forms的样式

我们修改forms的样式,不能随着自己的想法,要安装模板的格式

给forms添加bootstrap样式

循环生成表单

 

代码如下:

{% block content %}
    <!--模态框展示部分-->
    <!--
    tabindex  table 导航的顺序
    role = dialog 指定展示的样式(角色)为模态框
    aria-labelledby = "MyLabel" 获取值
    footer 页脚
    -->
    <div class="modal fade" data-toggle="modal" id="register_user_modal" tabindex="-1" role="dialog"
         aria-labelledby="Mylabel" aria-hidden="true">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
                    <h4 class="modal-title" id="MyLabel">用户注册</h4>
                </div>
                <form method="post" id="register_form" enctype="multipart/form-data">
                    {% csrf_token %}
                    <div class="modal-body">
                        {% for formitem in user_from %}
                            <div class="form-group input-group">
                                <span class="input-group-addon">{{ formitem.label }}</span>
                                {{ formitem }}
                            </div>
                        {% endfor %}
                    </div>

                    <div class="modal-footer">
                        <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
                        <button type="submit" class="btn btn-primary" id="add_user_submit">提交</button>
                    </div>
                </form>
            </div>
        </div>
    </div>
    <!--模态框展示部分结束-->
    <div class="modal fade" data-toggle="modal" id="logout_user_modal" tabindex="-1" role="dialog"
         aria-labelledby="Mylabel" aria-hidden="true">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
                    <h4 class="modal-title" id="MyLabel">用户注销</h4>
                </div>
                <form action="{% url 'logout' %}" method="get" id="logout_dialog" >
                    {% csrf_token %}
                    <div class="modal-body">
                            <div class="form-group input-group">
                                退出当前用户?
{#                                <span class="input-group-addon">{{ formitem.label }}</span>#}
{#                                {{ formitem }}#}
                            </div>
                    </div>

                    <div class="modal-footer">
                        <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
                        <button type="submit" class="btn btn-primary" id="logout_user_submit">提交</button>
                    </div>
                </form>
            </div>
        </div>
    </div>
    <!--模态框展示部分结束-->
    <div class="container-fluid">
        <div class="col-md-6">

        </div>
    </div>
{% endblock %}

基于JQ的前端校验

From前端校验对于所有同学来说,都是一个难点,今天推荐jq扩展框架jq_validate是jq扩展的校验库,拥有丰富的校验功能,有jq开发小组成员开发。

  1. 导入框架

下载jq-validation包

取出自己需要的jq脚本

Jquery.validate.min.js 校验功能的压缩包

Jquery.validate支持40多种语言,我们还需要下载汉化包

我们将两个js脚本复制到我们的目录下

然后执行导入

form上添加校验属性:

代码:

# !/usr/bin/env python
# -*- coding: utf-8 -*-

from django import forms
from django.forms import widgets


class CMDBUserForm(forms.Form):
    name = forms.CharField(
        max_length=6,  # 长度限制的验证优先级高于前端验证,前后端都要验证,且限制规则相同
        min_length=2,
        label='用户账号',
        widget=widgets.TextInput(
            attrs={
                'class': 'form-control',
                'required': '',
                'minlength': 2,
                'maxlength': 6,
            }
        ),
        error_messages={
            'max_length':'用户名最大6位',
            'min_length':'用户名最小2位',
            'required':'用户名不能为空'
        }
    )
    password = forms.CharField(
        max_length=6,
        min_length=2,
        label='用户密码',
        widget=widgets.PasswordInput(
            attrs={
                'class': 'form-control',
                'required': '',
                'minlength': 2,
                'maxlength': 6,
            }
        )
    )
    nickname = forms.CharField(
        max_length=6,
        min_length=2,
        label='用户姓名',
        widget=widgets.TextInput(
            attrs={
                'class': 'form-control',
                'required': '',
                'minlength': 2,
                'maxlength': 6,
            }
        )
    )
    phone = forms.CharField(
        max_length=11,
        min_length=11,
        label='用户电话',
        widget=widgets.TextInput(
            attrs={
                'class': 'form-control',
                'required': '',
                'minlength': 11,
                'maxlength': 11,
            }
        )
    )
    email = forms.EmailField(
        label='用户邮箱',
        widget=widgets.EmailInput(
            attrs={
                'class': 'form-control',
                'required': '',
            }
        )
    )
    photo = forms.ImageField(
        label='用户照片',
        allow_empty_file=True,
        widget=widgets.FileInput(
            attrs={
                'id': 'logo_file',
                'class': 'file-input-new btn btn-primary btn-file',
                'style': " margin: auto;",
                'required': '',
            }
        )
    )
前端js定义校验规则和提示

 

代码:

{% block script %}
    <!-- jQuery -->
    <script src="/static/vendor/jquery/jquery.min.js"></script>

    <!-- Bootstrap Core JavaScript -->
    <script src="/static/vendor/bootstrap/js/bootstrap.min.js"></script>

    <!-- Metis Menu Plugin JavaScript -->
    <script src="/static/vendor/metisMenu/metisMenu.min.js"></script>

    <!-- DataTables JavaScript -->
    <script src="/static/vendor/datatables/js/jquery.dataTables.min.js"></script>
    <script src="/static/vendor/datatables-plugins/dataTables.bootstrap.min.js"></script>
    <script src="/static/vendor/datatables-responsive/dataTables.responsive.js"></script>

    <!-- Custom Theme JavaScript -->
    <script src="/static/dist/js/sb-admin-2.js"></script>

    <!-- 前端表单验证js,注意2个库的顺序 -->
    <script src="/static/vendor/jquery/jquery.validate.min.js"></script>
    <script src="/static/vendor/jquery/messages_zh.min.js"></script>

    <!-- Page-Level Demo Scripts - Tables - Use for reference -->
    <script>
        $().ready(
            function () {
                $('#register_form').validate(
                    {
                        <!-- 前端表单验证规则 -->
                        rules: {
                            id_name: {
                                required: true,
                                minlength: 2,
                                maxlength: 6,
                            },
                            id_password: {
                                required: true,
                                minlength: 2,
                                maxlength: 6,
                            },
                            id_nickname: {
                                required: true,
                                minlength: 2,
                                maxlength: 6,
                            },
                            id_phone: {
                                required: true,
                            },
                            id_email: {
                                required: true,
                            }
                        },
                        <!-- 前端表单验证失败提示消息 -->
                        messages: {
                            id_name: {
                                required: '用户名不能为空',
                                minlength: '用户名长度必须大于2',
                                maxlength: '用户名长度必须小于6',
                            },
                            id_password: {
                                required: '密码不能为空',
                                minlength: '密码长度必须大于2',
                                maxlength: '密码长度必须小于6',
                            },
                            id_nickname: {
                                required: '用户姓名不能为空',
                                minlength: '用户姓名长度必须大于2',
                                maxlength: '用户姓名长度必须小于6',
                            },
                            id_phone: {
                                required: '',
                                minlength: '请输入正确长度(不少于11位)的用户电话',
                                maxlength: '请输入正确长度(不大于11位)的用户电话',
                            },
                            id_email: {
                                required: '用户邮箱不能为空',
                            },
                        },
                        submitHandler: function (form) {
                            data = $('#register_form').serializeArray()//没有文件,可以用这个方式获取form数据
                            var formdata = new FormData();//获取含有文件的form数据
                            for (var k in data){
                                console.log(data[k])
                                formdata.append(data[k]['name'],data[k]['value'])
                            }
                            //添加文件到formdata
                            file = $('#logo_file')[0].files[0]
                            console.log(file)
                            formdata.append('photo',file)
                            //获取csrftoken,提交给到后端验证
                            var csrftoken = data[0]['value']
                            $.post({
                                url:'/index/',
                                data:formdata,
                                async:false,
                                traditional:true,//是否深度序列化数据,true为不深度
                                processData:false,//是否序列化
                                contentType:false,//信息的类型
                                beforeSend:function (xhr,settings) {
                                    xhr.setRequestHeader('X-CSRFToken',csrftoken)
                                },
                                <!--=========后台验证结果在此返回,前台判断显示==========-->
                                success:function (data) {
                                    console.log(data['data'])
                                    if (data['status'] == 'success'){
                                        toastr.success(data['data'])
                                        //等待弹出toastr后再刷新页面
                                        setTimeout(function(){ window.location.reload() }, 2000);
                                    }//保存失败,文件大小太大
                                    if (data['status'] == 'save fail'){
                                        toastr.error(data['data'])
                                    }
                                    if (data['status'] == 'is_valid error'){
                                        toastr.error(data['data'])
                                    }

                                },
                                error:function (error) {
                                    console.log(error['data'])
                                    toastr.error(error['data'])
                                },
                            })

                        },
                    }
                )
            }
        )
    </script>
{% endblock %}

注意:最长限制不会显示,只会超过最长长度后无法输入

完整代码如下:
前端:

{% extends 'base.html' %}

{% block title %}
    <title>S-CMDB管理系统 首页</title>
{% endblock %}
{% block style %}
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">

    <!-- Bootstrap Core CSS -->
    <link href="/static/vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">

    <!-- MetisMenu CSS -->
    <link href="/static/vendor/metisMenu/metisMenu.min.css" rel="stylesheet">

    <!-- DataTables CSS -->
    <link href="/static/vendor/datatables-plugins/dataTables.bootstrap.css" rel="stylesheet">

    <!-- DataTables Responsive CSS -->
    <link href="/static/vendor/datatables-responsive/dataTables.responsive.css" rel="stylesheet">

    <!-- Custom CSS -->
    <link href="/static/dist/css/sb-admin-2.css" rel="stylesheet">

    <!-- Custom Fonts -->
    <link href="/static/vendor/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css">
{% endblock %}
{% block navbar-brand %}
    <a class="navbar-brand" href="yl/index.html">S-CMDB管理系统</a>
{% endblock %}
{% block page-header %}
    <!--模态框触发部分-->
    <!--
        data-toggle 以何种形式展示模态框 modal、popover
        data-target 模态框id
    -->
    <div class="container-fluid">
        <div class="col-md-8">
            用户管理
        </div>
        <div class="col-md-4" style="text-align:right">
            <button class="btn btn-default" data-toggle="modal" data-target="#register_user_modal">用户注册</button>
            <button class="btn btn-default" data-toggle="modal" data-target="#logout_user_modal">用户退出</button>
        </div>
    </div>
    <!--模态框触发部分结束-->
{% endblock %}

{% block content %}
    <!--模态框展示部分-->
    <!--
    tabindex  table 导航的顺序
    role = dialog 指定展示的样式(角色)为模态框
    aria-labelledby = "MyLabel" 获取值
    footer 页脚
    -->
    <div class="modal fade" data-toggle="modal" id="register_user_modal" tabindex="-1" role="dialog"
         aria-labelledby="Mylabel" aria-hidden="true">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
                    <h4 class="modal-title" id="MyLabel">用户注册</h4>
                </div>
                <form method="post" id="register_form" enctype="multipart/form-data">
                    {% csrf_token %}
                    <div class="modal-body">
                        {% for formitem in user_from %}
                            <div class="form-group input-group">
                                <span class="input-group-addon">{{ formitem.label }}</span>
                                {{ formitem }}
                            </div>
                        {% endfor %}
                    </div>

                    <div class="modal-footer">
                        <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
                        <button type="submit" class="btn btn-primary" id="add_user_submit">提交</button>
                    </div>
                </form>
            </div>
        </div>
    </div>
    <!--模态框展示部分结束-->
    <div class="modal fade" data-toggle="modal" id="logout_user_modal" tabindex="-1" role="dialog"
         aria-labelledby="Mylabel" aria-hidden="true">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
                    <h4 class="modal-title" id="MyLabel">用户注销</h4>
                </div>
                <form action="{% url 'logout' %}" method="get" id="logout_dialog" >
                    {% csrf_token %}
                    <div class="modal-body">
                            <div class="form-group input-group">
                                退出当前用户?
{#                                <span class="input-group-addon">{{ formitem.label }}</span>#}
{#                                {{ formitem }}#}
                            </div>
                    </div>

                    <div class="modal-footer">
                        <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
                        <button type="submit" class="btn btn-primary" id="logout_user_submit">提交</button>
                    </div>
                </form>
            </div>
        </div>
    </div>
    <!--模态框展示部分结束-->
    <div class="container-fluid">
        <div class="col-md-6">

        </div>
    </div>
{% endblock %}
{#{% block content %}#}
{#    <h1>设备管理首页</h1>#}
{#{% endblock %}#}
{% block script %}
    <!-- jQuery -->
    <script src="/static/vendor/jquery/jquery.min.js"></script>

    <!-- Bootstrap Core JavaScript -->
    <script src="/static/vendor/bootstrap/js/bootstrap.min.js"></script>

    <!-- Metis Menu Plugin JavaScript -->
    <script src="/static/vendor/metisMenu/metisMenu.min.js"></script>

    <!-- DataTables JavaScript -->
    <script src="/static/vendor/datatables/js/jquery.dataTables.min.js"></script>
    <script src="/static/vendor/datatables-plugins/dataTables.bootstrap.min.js"></script>
    <script src="/static/vendor/datatables-responsive/dataTables.responsive.js"></script>

    <!-- Custom Theme JavaScript -->
    <script src="/static/dist/js/sb-admin-2.js"></script>

    <!-- 前端表单验证js,注意2个库的顺序 -->
    <script src="/static/vendor/jquery/jquery.validate.min.js"></script>
    <script src="/static/vendor/jquery/messages_zh.min.js"></script>

    <!-- Page-Level Demo Scripts - Tables - Use for reference -->
    <script>
        $().ready(
            function () {
                $('#register_form').validate(
                    {
                        <!-- 前端表单验证规则 -->
                        rules: {
                            id_name: {
                                required: true,
                                minlength: 2,
                                maxlength: 6,
                            },
                            id_password: {
                                required: true,
                                minlength: 2,
                                maxlength: 6,
                            },
                            id_nickname: {
                                required: true,
                                minlength: 2,
                                maxlength: 4,
                            },
                            id_phone: {
                                required: true,
                            },
                            id_email: {
                                required: true,
                            }
                        },
                        <!-- 前端表单验证失败提示消息 -->
                        messages: {
                            id_name: {
                                required: '用户名不能为空',
                                minlength: '用户名长度必须大于2',
                                maxlength: '用户名长度必须小于6',
                            },
                            id_password: {
                                required: '密码不能为空',
                                minlength: '密码长度必须大于2',
                                maxlength: '密码长度必须小于6',
                            },
                            id_nickname: {
                                required: '用户姓名不能为空',
                                minlength: '用户姓名长度必须大于2',
                                maxlength: '用户姓名长度必须小于6',
                            },
                            id_phone: {
                                required: '',
                                minlength: '请输入正确长度(不少于11位)的用户电话',
                                maxlength: '请输入正确长度(不大于11位)的用户电话',
                            },
                            id_email: {
                                required: '用户邮箱不能为空',
                            },
                        },
                        submitHandler: function (form) {
                            data = $('#register_form').serializeArray()//没有文件,可以用这个方式获取form数据
                            var formdata = new FormData();//获取含有文件的form数据
                            for (var k in data){
                                console.log(data[k])
                                formdata.append(data[k]['name'],data[k]['value'])
                            }
                            //添加文件到formdata
                            file = $('#logo_file')[0].files[0]
                            console.log(file)
                            formdata.append('photo',file)
                            //获取csrftoken,提交给到后端验证
                            var csrftoken = data[0]['value']
                            $.post({
                                url:'/index/',
                                data:formdata,
                                async:false,
                                traditional:true,//是否深度序列化数据,true为不深度
                                processData:false,//是否序列化
                                contentType:false,//信息的类型
                                beforeSend:function (xhr,settings) {
                                    xhr.setRequestHeader('X-CSRFToken',csrftoken)
                                },
                                <!--=========后台验证结果在此返回,前台判断显示==========-->
                                success:function (data) {
                                    console.log(data['data'])
                                    if (data['status'] == 'success'){
                                        toastr.success(data['data'])
                                        //等待弹出toastr后再刷新页面
                                        setTimeout(function(){ window.location.reload() }, 2000);
                                    }//保存失败,文件大小太大
                                    if (data['status'] == 'save fail'){
                                        toastr.error(data['data'])
                                    }
                                    if (data['status'] == 'is_valid error'){
                                        toastr.error(data['data'])
                                    }

                                },
                                error:function (error) {
                                    console.log(error['data'])
                                    toastr.error(error['data'])
                                },
                            })

                        },
                    }
                )
            }
        )

    </script>
{% endblock %}

后端view.py:

import os

from django.conf import settings
from django.http import JsonResponse
from django.shortcuts import render, render_to_response, HttpResponseRedirect
# Create your views here.
from django.views.generic import View

from Service.models import CMDBUser
from Users.forms import CMDBUserForm


def login_validate(func):
    def is_validate(instance, request, *args, **kwargs):
        if request.method == 'GET':
            print(request.path)
            if request.path == '/user/login':
                pass
            elif request.path == '/user/logout':  # 退出登陆
                instance.logout(request)

            print(request.GET)
            print(request.COOKIES)
            return HttpResponseRedirect('/login/')
        # 用户已经登入,进行注册操作
        elif request.method == 'POST' and request.POST and request.FILES:
            print('无需验证,返回给index')
            return func(instance, request)
        elif request.method == 'POST' and request.POST:

            print('is_validate')
            print(request.POST)
            print(request.COOKIES)
            if request.POST.get('username'):
                try:
                    # 判断数据库是否存在该用户
                    user = CMDBUser.objects.get(username=request.POST.get('username'))
                    # 该用已成功登陆,并有对应数据库里的用户名生成的cookies就可以不用再查询了,直接返回
                    # if request.COOKIES['login_ok_cookies'] == user.username:
                    #     return func(instance, request)

                    print(request.POST.get('username'))
                    # 密码判断
                    print(user.password)
                    if request.POST.get('password') == user.password:
                        return func(instance, request)
                    else:
                        print('用户%s  密码错误' % (user.username))
                        return HttpResponseRedirect('/login/')
                except:
                    print('%s 这个用户不存在' % (request.POST.get('username')))
                    return HttpResponseRedirect('/login/')
            else:
                print('test')

    return is_validate


def logout(request):
    print(request.COOKIES)
    # response = render_to_response('login.html')
    response = render(request, 'login.html')
    response.delete_cookie('login_ok_cookies')
    # response.delete_cookie('login_ok_cookie')
    response.delete_cookie('login_cookie')
    print(request.COOKIES)
    print(response.cookies)
    # return response
    return HttpResponseRedirect('/login/')


class index(View):
    '''
    用户管理
    '''

    @login_validate
    def get(self, request):
        print(request.method)
        print(request.GET)
        print(request)
        if request.path == '/user/echart':
            print(request.path)
            return render(request, 'echart_example.html', locals())
        elif request.path == '/user/login':
            return render_to_response('login.html')
        elif request.path == '/user/index' or request.path == '/index/':
            pass
        user_from = CMDBUserForm()
        print(locals())
        # if request.GET.get()
        return render(request, 'user_index.html', locals())

    @login_validate
    def post(self, request):

        # 用户注册提交
        if request.POST and request.FILES:
            ret = {'status': '', 'data': ''}
            print(request.POST)
            print(request.FILES)
            user_form = CMDBUserForm(data=request.POST, files=request.FILES)
            if user_form.is_valid():
                user = CMDBUser()
                user.username = user_form.cleaned_data['name']  # key值为form里的字段name
                user.password = user_form.cleaned_data['password']
                user.nickname = user_form.cleaned_data['nickname']
                user.phone = user_form.cleaned_data['phone']
                user.email = user_form.cleaned_data['email']

                # 判断上传文件大小,小于某值才能上传
                file = request.FILES.get('photo')  # 尽量不要使用user_form.cleaned_data['file']
                filepath = os.path.join(settings.BASE_DIR,
                                        'static\\images\\%s' % (user_form.cleaned_data['photo'].name))

                with open(filepath, 'wb') as f:
                    for chunk in file.chunks():
                        f.write(chunk)
                if os.path.getsize(str(filepath)) < 200000:  # 上传问文件小于200kB才能保存,并写入数据库
                    user.photo = filepath
                    user.save()
                    ret['status'] = 'success'
                    ret['data'] = '%s 用户添加成功' % (user.username)
                    print('%s 用户添加成功' % (user.username))
                else:
                    ret['status'] = 'save fail'
                    ret['data'] = '保存失败,%s的文件大小不能超过200KB' % (user_form.cleaned_data['photo'].name)
                    os.remove(filepath)
                    print('保存失败,%s的文件大小不能超过200KB' % (user_form.cleaned_data['photo'].name))
            else:
                print(user_form.errors)
                # ret['status'] = 'is_valid error'
                ret['data'] = user_form.errors[0]
            user_from = CMDBUserForm()  # 解决第一次注册后,再次点击用户注册无法显示form内容的问题
            jr = JsonResponse(ret)
            # return render(request, 'user_index.html', {'user_from':user_from,'data':jr})
            # return render(request, 'user_index.html', locals())
            return JsonResponse(ret)
        # 用户登陆提交
        elif request.POST:
            print(request.POST)
            print(request.COOKIES)
            user_from = CMDBUserForm()
            response = render(request, 'user_index.html', locals())
            response.set_cookie('login_ok_cookies', request.POST.get('username'), max_age=3600)
            print(request.POST)
            print(request.COOKIES)
            print(response.cookies)
            return response

    def logout(self,request):
        print(request.COOKIES)
        # response = render_to_response('login.html')
        response = render(request, 'login.html')
        response.delete_cookie('login_ok_cookies')
        # response.delete_cookie('login_ok_cookie')
        response.delete_cookie('login_cookie')
        print(request.COOKIES)
        print(response.cookies)
        # return response
        return HttpResponseRedirect('/login/')


# def echart(request):
#     print(request.path)
#     return render(request, 'echart_example.html', locals())



Form表单自定义校验
我们的form表单本身提供了好多写好的校验方法,比如:
Maxlenth
Minlienth
Email

但是还是不够我们在工作当中使用,所以forms推出了自定义校验

格式:

  1. 必须写在forms类里面
  2. 校验函数名称必须是clean_字段名称
  3. 所有要校验的数据都可以通过clean_data.get(字段名称)得到

原理如下:

  1. 如果判断不符合条件,请诱发ValidationError
  2. 并且如果符合判断,必须将值返回出来

基于cmdb的ajax表单提交

我们上面完成了基本注册了,下面我们来了解一下我们的django+ajax+form+img上传。

Ajax 提交图片

Ajax 提交表单+图片

  1. 从前端做起

写ajax步骤

  1. 收集数据
    <script>
        $().ready(
            function () {
                $('#register_form').validate(
                    {
                        <!-- 前端表单验证规则 -->
                        rules: {
                            id_name: {
                                required: true,
                                minlength: 2,
                                maxlength: 6,
                            },
                            id_password: {
                                required: true,
                                minlength: 2,
                                maxlength: 6,
                            },
                            id_nickname: {
                                required: true,
                                minlength: 2,
                                maxlength: 4,
                            },
                            id_phone: {
                                required: true,
                            },
                            id_email: {
                                required: true,
                            }
                        },
                        <!-- 前端表单验证失败提示消息 -->
                        messages: {
                            id_name: {
                                required: '用户名不能为空',
                                minlength: '用户名长度必须大于2',
                                maxlength: '用户名长度必须小于6',
                            },
                            id_password: {
                                required: '密码不能为空',
                                minlength: '密码长度必须大于2',
                                maxlength: '密码长度必须小于6',
                            },
                            id_nickname: {
                                required: '用户姓名不能为空',
                                minlength: '用户姓名长度必须大于2',
                                maxlength: '用户姓名长度必须小于6',
                            },
                            id_phone: {
                                required: '',
                                minlength: '请输入正确长度(不少于11位)的用户电话',
                                maxlength: '请输入正确长度(不大于11位)的用户电话',
                            },
                            id_email: {
                                required: '用户邮箱不能为空',
                            },
                        },
                        submitHandler: function (form) {
                            data = $('#register_form').serializeArray()//没有文件,可以用这个方式获取form数据
                            var formdata = new FormData();//获取含有文件的form数据
                            for (var k in data){
                                console.log(data[k])
                                formdata.append(data[k]['name'],data[k]['value'])
                            }
                            //文件的提交方式:添加文件到formdata
                            file = $('#logo_file')[0].files[0]
                            console.log(file)
                            formdata.append('photo',file)
                            //获取csrftoken,提交给到后端验证
                            var csrftoken = data[0]['value']
                            $.post({
                                url:'/index/',
                                data:formdata,
                                async:false,
                                traditional:true,//是否深度序列化数据,true为不深度
                                processData:false,//是否序列化
                                contentType:false,//信息的类型
                                beforeSend:function (xhr,settings) {
                                    xhr.setRequestHeader('X-CSRFToken',csrftoken)
                                },
                                <!--=========后台验证结果在此返回,前台判断显示==========-->
                                success:function (data) {
                                    console.log(data['data'])
                                    if (data['status'] == 'success'){
                                        toastr.success(data['data'])
                                        //等待弹出toastr后再刷新页面
                                        setTimeout(function(){ window.location.reload() }, 2000);
                                    }//保存失败,文件大小太大
                                    if (data['status'] == 'save fail'){
                                        toastr.error(data['data'])
                                    }
                                    if (data['status'] == 'is_valid error'){
                                        toastr.error(data['data'])
                                    }

                                },
                                error:function (error) {
                                    console.log(error['data'])
                                    toastr.error(error['data'])
                                },
                            })

                        },
                    }
                )
            }
        )
    </script>

如果你的form数据包含文件,我们提交需要用到js的一个类型,FormData

FormData.append(key,value) #添加数据

FormData.set(key,value) #修改数据

FormData.getAll(key) #获取值

声明FormData需要先

var formData = new FromData

完整的form表单数据

收集接口

首先简单编写一个接口,进行了子urls编程

发起请求

FormData将csrf值出入当中之后要进行类似json的封装,所以会失效,csrf实际上如果交易的话,是在请求头部的

代码如下:

优化ajax接收接口。

Ajax注册完整代码

user_index.html:

 

<script>
        $().ready(
            function () {
                $('#register_form').validate(
                    {
                        <!-- 前端表单验证规则 -->
                        rules: {
                            id_name: {
                                required: true,
                                minlength: 2,
                                maxlength: 6,
                            },
                            id_password: {
                                required: true,
                                minlength: 2,
                                maxlength: 6,
                            },
                            id_nickname: {
                                required: true,
                                minlength: 2,
                                maxlength: 4,
                            },
                            id_phone: {
                                required: true,
                            },
                            id_email: {
                                required: true,
                            }
                        },
                        <!-- 前端表单验证失败提示消息 -->
                        messages: {
                            id_name: {
                                required: '用户名不能为空',
                                minlength: '用户名长度必须大于2',
                                maxlength: '用户名长度必须小于6',
                            },
                            id_password: {
                                required: '密码不能为空',
                                minlength: '密码长度必须大于2',
                                maxlength: '密码长度必须小于6',
                            },
                            id_nickname: {
                                required: '用户姓名不能为空',
                                minlength: '用户姓名长度必须大于2',
                                maxlength: '用户姓名长度必须小于6',
                            },
                            id_phone: {
                                required: '',
                                minlength: '请输入正确长度(不少于11位)的用户电话',
                                maxlength: '请输入正确长度(不大于11位)的用户电话',
                            },
                            id_email: {
                                required: '用户邮箱不能为空',
                            },
                        },
                        submitHandler: function (form) {
                            data = $('#register_form').serializeArray()//没有文件,可以用这个方式获取form数据
                            var formdata = new FormData();//获取含有文件的form数据
                            for (var k in data){
                                console.log(data[k])
                                formdata.append(data[k]['name'],data[k]['value'])
                            }
                            //文件的提交方式:添加文件到formdata
                            file = $('#logo_file')[0].files[0]
                            console.log(file)
                            formdata.append('photo',file)
                            //获取csrftoken,提交给到后端验证
                            var csrftoken = data[0]['value']
                            $.post({
                                url:'/index/',
                                data:formdata,
                                async:false,
                                traditional:true,//是否深度序列化数据,true为不深度
                                processData:false,//是否序列化
                                contentType:false,//信息的类型
                                beforeSend:function (xhr,settings) {
                                    xhr.setRequestHeader('X-CSRFToken',csrftoken)
                                },
                                <!--=========后台验证结果在此返回,前台判断显示==========-->
                                success:function (data) {
                                    console.log(data['data'])
                                    if (data['status'] == 'success'){
                                        toastr.success(data['data'])
                                        //等待2s后弹出toastr后再刷新页面
                                        setTimeout(function(){ window.location.reload() }, 2000);
                                    }//保存失败,文件大小太大
                                    if (data['status'] == 'save fail'){
                                        toastr.error(data['data'])
                                    }
                                    if (data['status'] == 'is_valid error'){
                                        toastr.error(data['data'])
                                    }

                                },
                                error:function (error) {
                                    console.log(error['data'])
                                    toastr.error(error['data'])
                                },
                            })

                        },
                    }
                )
            }
        )
    </script>

我们完成了注册的核心功能,但是我们还有很大的扩展空间,比如说

注册成功 提示

注册成功 跳转登录(凡是涉及到CMDB或者BIM系统开发,或者其他的管理平台,我们不设置外部注册 )

人物画像

BIM管理

管理流程

 

基于SB-Admin的图表绘制

我们在做管理平台的时候,难免会做各式各样的可视化图标,当前市场上已经有很多开发好的js框架,我们今天来学习echart.js绘图。

  1. 下载echart.js放入目录

  1. 导入echart.js

{% extends "blank.html" %}

{% block title %}
    echartsExample
{% endblock %}

{% block style %}
    <script src = "/static/js/echarts.min.js"></script>
{% endblock %}

{% block label %}
    echartsExample
{% endblock %}

{% block content %}
    
{% endblock %}

 

  1. 开始绘图

{% extends "blank.html" %}

{% block title %}
    EchartsExample
{% endblock %}

{% block style %}
    <script src = "/static/js/echarts.min.js"></script>
{% endblock %}

{% block label %}
    EchartsExample
{% endblock %}

{% block content %}
    <div id = "panel" style = "height: 500px; width: 500px;">

    </div>
    <script>
        //初始化画布
        var myChart = echarts.init(document.getElementById("panel"))
        //定义选项参数
        options = {
            title: {
                text: "我的柱状图"
            },
            tooltip:{},
            legend:{
                data:["学科"]
            },
            xAxis: {
                data:["python","php","jave","linux","c"]
            },
            yAxis: {},
            series: [
                {
                    name: "学科",
                    type: "bar",
                    data:[1,4,2,5,3]
                }
            ]
        };
        myChart.setOption(options)
    </script>
{% endblock %}

效果如下

  1. 总结规律

1、echarts 需要定义画布,而且选择器最好用js

    2、echarts主要有以下几种类型

1、bar 柱状图

2、line 折线图

3、gauge 仪表盘

4、pie 饼状图

5、island 孤岛图

6、funnel 漏斗图

 

猜你喜欢

转载自blog.csdn.net/weixin_35264169/article/details/82078408