Python+Django+Hadmin的初级使用V1.0

时间:2019-02-11
本文章向大家介绍Python+Django+Hadmin的初级使用V1.0,主要包括Python+Django+Hadmin的初级使用V1.0使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

关于@Python+Django+Hadmin

关于Python+Django+Hadmin的初级使用V1.0

大家好,上次我发布了一个基本用法,这次我把Hadmin前端的增、删、改、查的功能都结合进去了,实现一整套的动静分离的框架流程,供大家参考使用,随后,我会不断的再这个上面增加一些新的功能和模块上去,希望大家喜欢,谢谢!前后端的代码分享在这里。

models.py

from django.db import models

class Students(models.Model):
    school_name = models.CharField(max_length=10)
    grade_num = models.IntegerField()
    class_num = models.IntegerField()
    name = models.CharField(max_length=30)
    sex = models.CharField(max_length=2)
    age = models.IntegerField()
    hob = models.CharField(max_length=50)


def _str__(self):
    return 'school_name:'+self.school_name+';grade_num:'+str(self.grade_num)+';class_num :'\
     + str(self.class_num)+';name:'+self.name+';sex:'+self.sex+';age:'+self.age+';hob:'+self.hob

settings.py

import os
import pymysql
pymysql.install_as_MySQLdb()

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'StudentS.apps.StudentsConfig',
    'ClassStu'                     //上面都是自带的,这个是默认的工程名,是需要自己添加的
]

//这格式数据库连接信息
DATABASES = {          
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'ClassStu',
        'USER': 'root',
        'PASSWORD': '12345678',
        'HOST': 'localhost',
        'PORT': '3306',
    }
}

views.py

from django.contrib.auth import authenticate
from django.shortcuts import render
from django.http.response import JsonResponse
from django.http import HttpResponseRedirect
from django.contrib.auth.models import User
from django.shortcuts import render_to_response
import pymysql
import math


# Create your views here.
from django.views.decorators.csrf import csrf_protect
from StudentS.models import Students

@csrf_protect
def opera(request):
    cook = request.COOKIES.get('cookie_username')
    if cook is not None:
        if request.POST:
            # oper = request.get["oper"]
            # 开始进行插入数据库操作
            if request.POST['oper'] == 'add':
                Students.objects.create(school_name=request.POST['school_name'], grade_num=request.POST['grade_num'],
                                        class_num=request.POST['class_num'], name=request.POST['name'], sex=request.POST['sex'],
                                        age=request.POST['age'], hob=request.POST['hob']),
                # return render(request, 'add.html', {'result': "成功添加数据!"})
            # 开始进行更新记录集操作
            elif request.POST['oper'] == 'edit':
                Students.objects.filter(id=request.POST['id']).update(school_name=request.POST['school_name'], grade_num=request.POST['grade_num'],
                                        class_num=request.POST['class_num'], name=request.POST['name'], sex=request.POST['sex'],
                                        age=request.POST['age'], hob=request.POST['hob'])
            else:
                Students.objects.filter(id=request.POST['id']).delete()
    return render(request, 'index.html')

# 首页如果没有得到Cookies则放回到login.html进行认证
def show(request):
    cook = request.COOKIES.get('cookie_username')
    if cook is not None:
        return render(request, 'index.html', {'aa': cook})    # request,地址,参数
    else:
        return render(request, 'login.html')

# 默认打开login.html页面
def index(request):
    return render(request, 'login.html')    # request,地址,参数


def login(request):
    if request.method == 'POST':  # 判断是否为post提交方式
        username = request.POST.get('username', ' ')  # 通过post.get()方法获取输入的用户名及密码
        password = request.POST.get('password', ' ')
        user = authenticate(username=username, password=password)
        # userpassjudge = User.objects.filter(username=username, password=password)
        if user is not None:   # 判断用户名及密码是否正确
            response = HttpResponseRedirect('/show/')           # 如果正确,(这里调用另一个函数,实现登陆成功页面独立,使用HttpResponseRedirect()方法实现
            response.set_cookie('cookie_username', username, 3600)
            return response
        else:
            return render(request, 'login.html', {'error': 'username or password error'})  # 不正确,通过render(request,"login.html")方法在error标签处显示错误提示

# 定义需要传送给Hadmin前端页面的Jason数据集
def data(request):
    context = {}  # 封装返回参数
    results = Students.objects.order_by("-id")
    r = []
    for i in results:
        tmp = {}
        tmp["id"] = i.id
        tmp["school_name"] = i.school_name
        tmp["grade_num"] = i.grade_num
        tmp["class_num"] = i.class_num
        tmp["name"] = i.name
        tmp["sex"] = i.sex
        tmp["age"] = i.age
        tmp["hob"] = i.hob
        r.append(tmp)
        rowNum = 10
    return JsonResponse({"rows": r, "records": len(r), "pages": math.ceil(len(r)/rowNum)})

urls.py

from django.conf.urls import url
from django.urls import path, include
from django.contrib import admin

from StudentS import views

urlpatterns = [
    url(r'^$', views.index),
    url(r'^opera/$', views.opera),
    url(r'^show/$', views.show, name='show'),
    url(r'^data/$', views.data),
    url(r'^login/$', views.login, name='login'),
    url(r'^admin/',  admin.site.urls),
]

index.html(显示数据库记录数)

{% load staticfiles %}

<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title> - jqGird</title>
    <meta name="keywords" content="">
    <meta name="description" content="">

    <link rel="shortcut icon" href="favicon.ico"> <link href="{% static 'css/bootstrap.min.css'%}?v=3.3.6 " rel="stylesheet">
    <link href="{% static 'css/font-awesome.css'%}?v=4.4.0 " rel="stylesheet">

    <!-- jqgrid-->
    <link href="{% static 'css/plugins/jqgrid/ui.jqgrid.css'%}?0820" rel="stylesheet">

    <link href="{% static 'css/animate.css'%}" rel="stylesheet">
    <link href="{% static 'css/style.css'%}?v=4.1.0 " rel="stylesheet">	
    <style>
        /* Additional style to fix warning dialog position */

        #alertmod_table_list_2 {
            top: 900px !important;
        }
    </style>
</head>
<body class="gray-bg">
    <div class="wrapper wrapper-content  animated fadeInRight">
        <div class="row">
            <div class="col-sm-12">
                <div class="ibox ">
                    <div class="ibox-title">
                        <h5>学生信息表</h5>
                    </div>
                    <div class="ibox-content">
                        <div class="jqGrid_wrapper">
                            <table id="table_list_1"></table>
                            <div id="pager_list_1"></div>
                        </div>
                        <p>&nbsp;</p>
                        <div class="jqGrid_wrapper">
                            <table id="table_list_2"></table>
                            <div id="pager_list_2"></div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <!-- 全局js -->
{#    <script src="{% static 'js/jquery.cookie.js' %}?v=1.4.1"></script>#}
    <script src="{% static 'js/jquery.min.js' %}?v=2.1.4"></script>
    <script src="{% static 'js/bootstrap.min.js' %}?v=3.3.6"></script>

    <!-- Peity -->
    <script src="{% static 'js/plugins/peity/jquery.peity.min.js' %}"></script>

    <!-- jqGrid -->
    <script src="{% static 'js/plugins/jqgrid/i18n/grid.locale-cn.js' %}?0820"></script>
    <script src="{% static 'js/plugins/jqgrid/jquery.jqGrid.min.js' %}?0820"></script>

    <!-- 自定义js -->
    <script src="{% static 'js/content.js' %}?v=1.0.0"></script>

    <!-- Page-Level Scripts -->
    <script>

        function schoolcheck(value,school_name) {
            if (value == "")
               return [false,"学校: 此字段必需"];
            else
               return [true,""];
            }

        $(document).ready(function () {
            $.jgrid.defaults.styleUI = 'Bootstrap';
            // Examle data for jqGrid
            var mydata = ""
            $("#table_list_2").jqGrid({
                url: "/data/",
                multiselect : true,             //是否可以多选,第一列会出现多选按钮控件
                loadonce: true,                 //如果是json数据加载,只加载一次,动静分离,分页完全使用前端来分页,数据显示无需再与后端服务器进行交互
                datatype: "json",               //接收服务传过来的标准json串
                height: 450,                    //主表格的高度
                pager: "#pager_list_2",         //导航栏对象,必须是一个有效的html元素,位置可以随意
                viewrecords: true,              //是否要显示总记录数信息
                caption: "学生信息表",           //表格名称
                hidegrid: false,                //表格是否隐藏
                sortname:'id',                  //设置默认排序字段
                sortorder: 'desc',              //倒序
                editurl: "/opera/",
                {#editData:{csrfmiddlewaretoken: '{{ csrf_token }}'},#}
                autowidth: true,
                shrinkToFit: true,
                recordpos: 'right', //总记录显示位置:居右
                rownumbers: true,   //是否显示记录序号,true显示,false隐藏
                rownumWidth: 50,
                rowNum: 10,
                rowList: [10, 20, 30],
                colNames: ['id', '学校', '年级', '班级', '姓名', '性别', '年龄','爱好'],
                colModel: [
                    {   name: 'id', index: 'id', editable: true, width: 60, sorttype: "int", search: true,hidden:true,},
                    {   name: 'school_name', index: 'school_name', editable: true, width: 90, editrules:{custom:true,custom_func:schoolcheck}},
                    {   name: 'grade_num', index: 'grade_num', editable: true, width: 40, sorttype: "int", editrules:{required:true,number:true}},
                    {   name: 'class_num', index: 'class_num', editable: true, width: 40, align: "left", sorttype: "int", editrules:{required:true,number:true}},
                    {   name: 'name', index: 'name', editable: true, width: 80, align: "left", editrules:{required:true}},
                    {   name: 'sex', index: 'sex', editable: true, width: 80, align: "left", editrules:{required:true}},
                    {   name: 'age', index: 'age', editable: true, width: 100, sorttype: "int", editrules:{required:true,number:true}},
                    {   name: 'hob', index: 'hob', editable: true, width: 80, align: "left", editrules:{required:true}},
                ],
                 jsonReader: {                          //描述json 数据格式的数组,需修改
			        	root: 'rows',                   // 接收并显示所有数组数据
				    	page: "current",                // json中代表当前页码的数据
				    	total: "pages",                 // json中代表页码总数的数据
				    	records: "total",               // json中代表数据行总数的数据
				    	repeatitems: false,             // 如果设为false,则jqGrid在解析json时,会根据name来搜索对应的数据元素(即可以json中元素可以不按顺序);而所使用的name是来自于colModel中的name设定。
				    	{#cell: "cell",#}
				    	{#id: "fRoleId",#}
				    	{#userdata: "userdata",#}

				    },

                prmNames : {
                    page:"page", // 表示请求页码的参数名称
                    rows:"rows", // 表示请求行数的参数名称
                    sort: "sidx", // 表示用于排序的列名的参数名称
                    order: "sord", // 表示采用的排序方式的参数名称
                    search:"_search", // 表示是否是搜索请求的参数名称
                    nd:"nd", // 表示已经发送请求的次数的参数名称
                    id:"id", // 表示当在编辑数据模块中发送数据时,使用的id的名称
                    oper:"oper", // operation参数名称
                    editoper:"edit", // 当在edit模式中提交数据时,操作的名称
                    addoper:"add", // 当在add模式中提交数据时,操作的名称
                    deloper:"del", // 当在delete模式中提交数据时,操作的名称

                },


                loadComplete: function (a, b, c) {
                                jQuery("#table_list_2").jqGrid('setLabel', 'rn', '序号', {
                                    'text-align': 'center',
                                    'vertical-align': 'middle',
                                    "width": "50"
                                });
                                $("table[role='grid']").each(function () {//jqgrid 创建的表格都有role属性为grid
                                    $('.' + $(this).attr("class") + ' tr:first th:first').css("width", "50"); //使表头的序号列宽度为40
                                    $('.' + $(this).attr("class") + ' tr:first td:first').css("width", "50"); // 使表体的序号列宽度为40
                                });
                            },


            });
            // Add selection
            {#$("#table_list_2").setSelection(4, true);#}

            // Setup buttons
            $("#table_list_2").jqGrid('navGrid', '#pager_list_2', {
                edit: true,
                add: true,
                del: true,
                search: true,
                addtext: '添加',
                edittext: '编辑',
                deltext: '删除',
                searchtext:'查找',
                position : 'left',
                height: 200,
                closeAfterEdit:true,
                closeAfterAdd: true,        //Closes the add window after add
                reloadAfterSubmit: true,
                closeOnEscape:true,
            });

            // Add responsive to jqGrid
            $(window).bind('resize', function () {
                var width = $('.jqGrid_wrapper').width();
                $('#table_list_2').setGridWidth(width);

            });

        });

        //Start--以下为解决添加或者编辑表单数据时用于传递crsf_token的两个javascript的代码段
            // 这个才是重点的代码,必须写
             function getCookie(name) {
                var cookieValue = null;
                if (document.cookie && document.cookie !== '') {
                var cookies = document.cookie.split(';');
                for (var i = 0; i < cookies.length; i++) {
                    var cookie = jQuery.trim(cookies[i]);
                    // Does this cookie string begin with the name we want?
                    if (cookie.substring(0, name.length + 1) === (name + '=')) {
                        cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                        break;
                         }
                    }
                 }
                 return cookieValue;
             }

            // 这个才是重点的代码,必须写
             function csrfSafeMethod(method) {
            // these HTTP methods do not require CSRF protection
                 return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
                }
                csrftoken = getCookie('csrftoken');
                $.ajaxSetup({  //添加头部信息,csrftoken, 把token塞入头部
                beforeSend: function(xhr, settings) {
                if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                    xhr.setRequestHeader("X-CSRFToken", csrftoken);
                    }
                }
            });
        //End--以上为解决添加或者编辑表单数据时用于传递crsf_token的两个javascript的代码段

    </script>


</body>

</html>

添加记录图片

添加记录的时候,需要对字段进行判断,比如不能为空、必须是数字等,在index.html的前端页已经详细的定义,请看index.html页面的注释

删除记录图片

删除记录前端使用默认的Hadmin框架,后端在View.py里面编写后台删除的代码段即可。

编辑记录图片

编辑记录前端使用默认的Hadmin框架,后端在View.py里面编写后台编辑的代码段即可。