python django+mysql+bootstrap增删改查

python django+mysql+bootstrap增删改查

#安装mysql连接
pip3 install pymysql#安装pymysql
访问mysql运行异常参考https://blog.csdn.net/weixin_33127753/article/details/89100552

开发工具JetBrains

修改数据库连接地址
settings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'test',         #数据库名称
        'HOST': '127.0.0.1',    #IP
        'PORT': '3307',         #端口
        'USER': 'root',         #账号
        'PASSWORD':'123456',    #密码
        'CONN_MAX_AGE': None    #长连接
    }
}

在这里插入图片描述


python manage.py makemigrations # 将类(数据库)的变化提交
python manage.py migrate # 执行变化
执行结果

models.py代码

from django.db import models


#定义图书模型类BookInfo
class BookInfo(models.Model):
    id = models.AutoField(primary_key=True)  # 创建自增的一个主键
    name = models.CharField(max_length=255, verbose_name='名称')
    price = models.CharField(max_length=255, verbose_name='Price')
    createdate = models.DateTimeField(verbose_name='添加日期')

    class Meta:
        db_table = 'tb_books'  # 指明数据库表名
        verbose_name = '图书'  # 在admin站点中显示的名称

        verbose_name_plural = verbose_name  # 显示的复数名称

    def __str__(self):
        """定义每个数据对象的显示信息"""
        return self.name

在这里插入图片描述


urls.py添加连接

	url(r'^$',views.index),#加载页面
    url(r'data',views.tb_book_json),#MySQL列表数据
    url(r'info',views.tb_book_info),#修改获取数据
    url(r'save',views.tb_book_save),#添加,修改保存
    url(r'del',views.tb_book_del),#删除,批量删除

views.py

# Create your views here.

from django.shortcuts import render#导入render模块
from django.http.response import JsonResponse
from lanquan import models#引用models
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
import logging
import datetime
from django.views.decorators.csrf import csrf_exempt
logger = logging.getLogger('stu')# 指定所用的logger



def index(request):
    return render(request,'index.html')#通过render模块把index.html这个文件返回到前端


def tb_book_json(request):
    response = {}
    """
    #不分页使用
    ret = models.BookInfo.objects.all().order_by("id")
    response["records"] = list(ret.values())
    response['total'] = models.BookInfo.objects.all().count()
    return JsonResponse(response)"""
    #分页
    offset = int(request.GET.get('offset'))
    limit = int(request.GET.get('limit'))
    keyword = request.GET.get('KEYW')
    if keyword:
        tb_book_list = models.BookInfo.objects.values('id', 'name', 'price').filter(name__contains=keyword).order_by("id")
    else:
        tb_book_list = models.BookInfo.objects.values('id', 'name', 'price').order_by("id")
    if tb_book_list:
        paginator = Paginator(tb_book_list, limit)
        try:
            page_object_list = paginator.page(offset / limit + 1)
            logger.info('获取数据成功,path:' + request.path)
        except PageNotAnInteger:
            logger.error('If page is not an integer, deliver first page.,path:' + request.path)
            page_object_list = paginator.page(1)
        except EmptyPage:
            logger.error('If page is out of range (e.g. 9999), deliver last page of results.,path:' + request.path)
            page_object_list = paginator.page(paginator.num_pages)

    """rows = []
    for item in page_object_list:
        # 将数组中的每个元素提取出来拼接为rows的内容
        rows.append({'id': item['id'], 'name': item['name'], 'price': item['price']})"""

    response["records"] = page_object_list.object_list
    if keyword:
        response['total'] = models.BookInfo.objects.filter(name__contains=keyword).count()
    else:
        response['total'] = models.BookInfo.objects.all().count()
    return JsonResponse(response)


#edit修改获取数据
@csrf_exempt
def tb_book_info(request):
    response = {}
    keyid = int(request.POST.get('id'))
    response['row'] = list(models.BookInfo.objects.filter(id=keyid).values('id', 'name', 'price'))
    return JsonResponse(response)


#add,edit 保存
@csrf_exempt
def tb_book_save(request):
    response = {}
    keyid = int(request.POST.get('id'))
    name = request.POST.get('name')
    price = request.POST.get('price')
    if keyid == 0:
        #print("添加:" + str(name) + ";" + str(price))
        entity = models.BookInfo()
        entity.name = name
        entity.price = price
        entity.createdate = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        # 调用save则保存数据到数据库中
        try:
            entity.save()
            response['row'] = "ok"
        except MyError as e:
            response['row'] = "error"
            response['message'] = e.msg
    else:
        #print("修改:" + str(keyid) + ";" + str(name) + ";" + str(price))
        try:
            models.BookInfo.objects.filter(id=keyid).update(name=name, price=price)
            response['row'] = "ok"
        except MyError as e:
            response['row'] = "error"
            response['message'] = e.msg
    return JsonResponse(response)


#删除,批量删除根据ID
@csrf_exempt
def tb_book_del(request):
    response = {}
    ids = request.POST.get('ids')
    try:
        models.BookInfo.objects.extra(where=['id IN (' + ids + ')']).delete()
        response['row'] = "ok"
    except MyError as e:
        response['row'] = "error"
        response['message'] = e.msg
    return JsonResponse(response)


class MyError(Exception):
    def __init__(self, msg):
        self.msg = msg

    def __str__(self):
        return self.msg


模板样式目录

在这里插入图片描述


templates/index.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>test</title>
        <link rel="stylesheet" href="/static/css/bootstrap.min.css">
        <link rel="stylesheet" href="/static/css/bootstrap-table.min.css">
        <link rel="stylesheet" href="/static/css/font-awesome.min.css">
        <link rel="stylesheet" href="/static/css/util.css">
    </head>
    <body>
    <div class="container">
        <div id="toolbar" >
            <ul class="searchul">
                <li class="lileft"><span class="input-icon"><input  type="text" id="keyword" value="" placeholder="Item Name"><i class="icon-search"></i></span></li>
                <li class="lileft"><button type="button" class="btn btn-mini btn-light" onclick="boottable.refresh();" title="搜索"><i class="icon-search"></i></button></li>
                <li class="lileft"><button type="button" class="btn btn-mini btn-success" onclick="boottable.add()"><i class="icon-plus"></i>添加</button></li>
                <li class="lileft"><button type="button" class="btn btn-mini btn-danger" onclick="boottable.delall();"><i class="icon-trash"></i>批量删除</button></li>
            </ul>
        </div>
        <table id="table"></table>
    </div>
    </body>
    <script type="text/javascript" src="/static/js/jquery.min.js"></script>
    <script type="text/javascript" src="/static/js/bootstrap.min.js"></script>
    <script type="text/javascript" src="/static/js/bootstrap-table.js"></script>
    <script type="text/javascript" src="/static/js/layer/layer.js"></script>
<script type="text/javascript">
	var boottable = {
		loading:function(){
			boottable.gridload();
		},
		gridload:function(){
			$("#table").bootstrapTable({
				url : '/data', 		//请求后台的URL(*)
				toolbar : '#toolbar',
				method : 'get', 				//请求方式(*)
				striped : true, 				//是否显示行间隔色
				cache : false, 					//是否使用缓存,默认为true,所以一般情况下需要设置一下这个属性(*)
				pagination : true, 				//是否显示分页(*)
				sidePagination : "server", 		//分页方式:client客户端分页,server服务端分页(*)
				pageNumber : 1, 				//初始化加载第一页,默认第一页
				pageSize : 10, 	//每页的记录行数(*)
				uniqueId : 'id', 			//每一行的唯一标识,一般为主键列
				clickToSelect : true, 			//是否启用点击选中行
				height : 400,
				queryParams:function(params){
					params['KEYW'] = $.trim($("#keyword").val());
					return params;
				},
				columns : [
					{ checkbox : true , align : 'center',valign : 'middle' },
					{ title : 'ID', field : 'id', align : 'left', valign : 'middle'},
					{ title : 'Item Name', field : 'name', align : 'left', valign : 'middle'},
					{ title : 'Price', field : 'price', align : 'left', valign : 'middle'},
					{ title : '操作', align : 'left', valign : 'middle',  formatter:function(value, row, index) {
							return '<a class="btn btn-minier btn-info" onclick="boottable.edit(' + row.id + ')" title="修改"><i class="icon-edit"></i></a>&nbsp;<a class="btn btn-minier btn-danger" onclick="boottable.del(' + row.id + ');" title="删除"><i class="icon-trash"></i></a>';
						}
					}
				],
				responseHandler : function(res) { return { total : res.total, rows : res.records }; } ,
				onSearch : function(text){
					console.log("执行查询方法:查询值:"+text);
				}
			});
		},
		refresh:function(){
			$('#table').bootstrapTable('refresh', { url : '/data' });
		},
		add:function(){
			var a = layer.open({
			  type: 1,
			  title: '添加',
			  area: ['600px', '300px'],
			  shadeClose: true,
			  content: '<form class="bt-form pd20 pb70"><div class="line"><span class="tname">Item Name:</span><input type="text" class="bt-input-text" id="add_name" value="" style="width:330px"></div><div class="line"><span class="tname ">Price:</span><input type="text" class="bt-input-text" id="add_price" value="" style="width:330px"></div><div class="bt-form-submit-btn"><button type="button" class="btn btn-danger btn-sm" onclick="layer.closeAll()">关闭</button><button type="button" id="dlok" class="btn btn-success btn-sm dlok">确定</button></div></form>'
			});
			$("#dlok").click(function() {
			    $.ajax({type: "POST",url: '/save',data :{ id: 0 ,name : $("#add_name").val(),price : $("#add_price").val() ,_ : Math.random()},cache : false,
                    success: function(data){
                        /*保存完成,关闭层*/
                        layer.close(a);
                        if(data.row == "ok"){
                            layer.msg("保存成功",{icon: 1});
                        }else{
                            layer.msg("保存失败"+data.message ,{icon: 2});
                        }
                        /*刷新列表*/
                        boottable.refresh();
                    },
                    error : function(XMLHttpRequest, textStatus, errorThrown) {
                        layer.msg(errorThrown,{icon: 2});
                    }
                });
			});
		},
		edit:function(id){
			/*ajax加载数据*/
            $.ajax({type: "POST",url: '/info',data :{ id: id ,_ : Math.random()},cache : false,
				success: function(data){
                    console.log(data)
                    var e = layer.open({
                      type: 1,
                      title: '修改',
                      area: ['600px', '300px'],
                      shadeClose: true,
                      content: '<div class="bt-form pd20 pb70"><input type="hidden" id="edit_id" value="'+data.row[0].id+'"><div class="line"><span class="tname">Item Name:</span><input type="text" class="bt-input-text" id="edit_name" value="'+data.row[0].name+'" style="width:330px"></div><div class="line"><span class="tname ">Price:</span><input type="text" class="bt-input-text" id="edit_price" value="'+data.row[0].price+'" style="width:330px"></div><div class="bt-form-submit-btn"><button type="button" class="btn btn-danger btn-sm" onclick="layer.closeAll()">关闭</button><button type="button" id="dlok" class="btn btn-success btn-sm dlok">确定</button></div></div>'
                    });
                    $("#dlok").click(function() {
                        $.ajax({type: "POST",url: '/save',data :{ id: $("#edit_id").val() ,name : $("#edit_name").val(),price : $("#edit_price").val() ,_ : Math.random()},cache : false,
				            success: function(data){
                                /*保存完成,关闭层*/
                                layer.close(e);
                                if(data.row == "ok"){
                                    layer.msg("保存成功",{icon: 1});
                                }else{
                                    layer.msg("保存失败"+data.message ,{icon: 2});
                                }
                                /*刷新列表*/
                                boottable.refresh();
                            },
                            error : function(XMLHttpRequest, textStatus, errorThrown) {
                                layer.msg(errorThrown,{icon: 2});
                            }
                        });
                    });
                },
				error : function(XMLHttpRequest, textStatus, errorThrown) {
                    layer.msg(errorThrown,{icon: 2});
                }
			});
		},
		del:function(id){
			var d = layer.confirm('确认删除数据?', { btn: ['确认','取消']},
			function(){
				var dl = layer.msg('正在删除中...', { icon: 16, time: 1000 * 60, });
				/*执行操作返回结果后关闭加载层*/
                $.ajax({type: "POST",url: '/del',data :{ ids: id ,_ : Math.random()},cache : false,
                    success: function(data){
                        layer.close(dl);
                        /*提示成功或失败(【icon: 1】成功,【icon: 2】失败))*/
                        if(data.row == "ok"){
                            layer.msg("删除成功",{icon: 1});
                        }else{
                            layer.msg("删除失败"+data.message ,{icon: 2});
                        }
                        /*刷新列表*/
                        boottable.refresh();
                    },
                    error : function(XMLHttpRequest, textStatus, errorThrown) {
                        layer.msg(errorThrown,{icon: 2});
                    }
                });
			},
			function(){
				/*取消操作关闭层*/
				layer.close(d);
			});
		},
		delall:function(){
			/*获取选中行数据*/
			var hrs = $("#table").bootstrapTable('getSelections');
			var strid = "";
			if (hrs.length < 1) {
				/*没有选中行*/
				layer.msg('请选择数据',{icon: 2});
			} else {
				for (var i = 0; i < hrs.length; i++) {
					if(strid != ""){
						strid += ",";
					}
					strid += hrs[i].id;
				}
			}
			/*判断行数据是否存在,存在即执行删除提示*/
			if(strid != ""){
				var d = layer.confirm('确认删除数据?', { btn: ['确认','取消']},
				function(){
					var dl = layer.msg('正在删除中...', { icon: 16, time: 1000 * 60, });
					/*执行操作返回结果后关闭加载层*/
                    $.ajax({type: "POST",url: '/del',data :{ ids: strid ,_ : Math.random()},cache : false,
                        success: function(data){
                            layer.close(dl);
                            /*提示成功或失败(【icon: 1】成功,【icon: 2】失败))*/
                            if(data.row == "ok"){
                                layer.msg("删除成功",{icon: 1});
                            }else{
                                layer.msg("删除失败"+data.message ,{icon: 2});
                            }
                            /*刷新列表*/
                            boottable.refresh();
                        },
                        error : function(XMLHttpRequest, textStatus, errorThrown) {
                            layer.msg(errorThrown,{icon: 2});
                        }
                    });
				},
				function(){
					/*取消操作关闭层*/
					layer.close(d);
				});
			}
		}
	}

    $(function () {
		boottable.loading();
    });
</script>
</html>

static/css/util.css手写部分样式

li {
    display: list-item;
    text-align: -webkit-match-parent;
}
user agent stylesheet
ul {
    list-style-type: disc;
}

.searchul {
    margin: 0;
	margin-left: -40px;
    margin-top: 5px;
}
.searchul .lileft {
    float: left;
    display: block;
    line-height: 23px;
    min-height: 28px;
    padding-right: 5px;
}

.btn-mini {
    padding: 0 5px;
    line-height: 22px;
    border-width: 2px;
    font-size: 12px;
}

.btn-minier {
    padding: 0 2px;
    line-height: 16px;
    border-width: 2px;
    font-size: 14px;
}
.bt-form {
    height: 100%;
}
.pb70 {
    padding-bottom: 70px;
}
.pd20 {
    padding: 20px;
}
.line {
    padding: 5px 0;
}
.line .tname {
    display: block;
    float: left;
    height: 32px;
    line-height: 32px;
    overflow: hidden;
    padding-right: 20px;
    text-align: right;
    text-overflow: ellipsis;
    white-space: nowrap;
    width: 100px;
}
.bt-input-text {
    border: 1px solid #ccc;
    height: 30px;
    line-height: 30px;
    padding-left: 5px;
    border-radius: 2px;
    -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
    -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
    transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
}
.bt-form-submit-btn {
    background: #f6f8f8;
    border-top: 1px solid #edf1f2;
    bottom: 0;
    left: 0;
    padding: 8px 20px 10px;
    position: absolute;
    text-align: right;
    width: 100%;
}
.bt-form-submit-btn .btn:first-child {
    margin-right: 4px;
}
.btn-danger, .btn-danger:focus {
    background-color: #d15b47!important;
    border-color: #d15b47;
}
.btn {
    vertical-align: inherit;
}
.btn-success {
    color: #fff;
    background-color: #20a53a;
    border-color: #20a53a;
}
.btn-group-sm>.btn, .btn-sm {
    padding: 5px 10px;
    font-size: 12px;
    line-height: 1.5;
    border-radius: 3px;
}

span.input-icon {
    display: inline-block;
}

.input-icon {
    position: relative;
    line-height: 20px;
}
.input-icon>input {
    padding-left: 24px;
    padding-right: 6px;
}
.input-icon>[class*=icon-] {
    padding: 0 3px;
    z-index: 2;
    position: absolute;
    top: 1px;
    bottom: 1px;
    left: 3px;
    line-height: 24px;
    display: inline-block;
    color: #909090;
    font-size: 16px;
}

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


在这里插入图片描述

原文地址:https://blog.csdn.net/lanquankk/article/details/98750454

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


前端工程师一般用的是Bootstrap的框架而不是样式,样式一般自己重新定义class类即可,主要样式要随具体情况而定包括位置任何带有class.btn的元素都会继承圆角灰色按钮的默认外观。但是Bootstrap提供了一些选项来定义按钮的样式。<buttontype="button"class="btn">基本
起步导入:<linkrel="stylesheet"href="bootstrap-3.3.7-dist/css/bootstrap.css"><scriptsrc="js/jquery-3.3.1.js"></script><scriptsrc="bootstrap-3.3.7-dist/js/bootstrap.js"></script>屏幕
(1)modal声明一个模态框(2)modal-dialog定义模态框尺寸(3)modal-lg定义大尺寸模态框(4)modal-sm定义小尺寸模态框(5)modal-header(6)modal-body(7)modal-footer<!doctypehtml><html><head><metacharset="utf-8"><title>模态框<itle><linkrel=&quo
图片在Bootstrap版本3中,通过为图片添加 .img-responsive 类可以让图片支持响应式布局。其实质是为图片设置了 max-width:100%;、 height:auto; 和 display:block; 属性,从而让图片在其父元素中更好的缩放。如果需要让使用了 .img-responsive 类的图片水平居
<inputtype="text"class="form-controldatepicker"style="padding:0.375rem0.75rem;"placeholder="开始时间"readonly="true" id="start_time"name="start_time"> $(".datepicke
目录bootstrap-treeview使用小记零、写在前面的话一、功能说明二、特性简述三、实战3.1依赖环境3.2数据源格式3.3Options选项3.4Methods方法3.5Events事件N-2、番外N-1、本文demoN、参考资料bootstrap-treeview使用小记零、写在前面的话p.s.bootst
  一、应用http://www.bootcss.com/进入bootstrap4或bootstrap3中文网,想要快速地将Bootstrap应用到你的项目中,有以下两种办法: 1、bootstrap可以在线引用,方法如下:A、CSS将引入Bootstrap样式表的 <link> 标签复制并粘贴到 <head> 中,并放在所有其他样式表之前。<!
第87节:Java中的Bootstrap基础与SQL入门前言复习什么是JQ?:writelessdomore写更少的代码,做更多的事找出所有兄弟:$("div").siblings()基本过滤器:选择器:过滤器$("div:first"):first:找到第一个元素:last:找到最后一个元素:even:找出偶数索引:odd:找出奇叔索引
1.bootstrap表单(1)form声明一个表单域(2)form-inline内联表单域(3)form-horizontal水平排列表单域(4)form-group表单组、包括表单文字和表单控件(5)form-control文本输入框、下拉列表控件样式(6)checkboxcheck-inline多选框样式(7)radioradio-inline单选框样式(8)input-group表单控件组
<!DOCTYPEhtml><htmllang="en"><head><metacharset="utf-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>首页<itle><
嗯。。。以前做ssh。应该是stratusspringhibernate。 然后现在来了一个新的需求。 要用java,bootstrap,oracle,springboot,jquery,mybatis。 开始,我也挺心虚的,但是后来一看,,,其实本没有必要这么虚。。。毕竟。。。这些东西,写的有问题。。。问题在于没有逻辑。 bootstrap,j
表格基本实例为任意 <table> 标签添加 .table 类可以为其赋予基本的样式—少量的内补(padding)和水平方向的分隔线。这种方式看起来很多余!?但是我们觉得,表格元素使用的很广泛,如果我们为其赋予默认样式可能会影响例如日历和日期选择之类的插件,所以我们选择将此样式独立出来。
1、问题背景   一般情况下,查询列表有查询条件、查询按钮和重置按钮,输入查询条件,点击查询按钮查询列表等数据;点击重置按钮会将查询条件恢复到原始状态 2、实现源码 <!DOCTYPEhtml><html> <head> <metacharset="UTF-8"> <title>Bootstrap-查询按钮和重置按钮<
Bootstrap简介什么是Bootstrap?Bootstrap官网框架:库liblibraryjQuery作为一个框架来讲,提供一套比较便捷的操作DOM的方式把大家都需要的功能预先写好到一些文件这就是一个框架Bootstrap让我们的Web开发更简单,更快捷;注意是Bootstrap不是BootStrap!这是一个词,不是
1.bootstrap图片img-responsive声明响应式图片2.bootstrap字体图标通过字体代替图标,font文件夹需要和css文件夹在同一目录3.bootst导航条(1)navbar声明导航条(2)navbar-default声明默认的导航条样式(3)navbar-inverse声明反白的导航条样式(4)navbar-static-top去掉导航条的圆角(5)n
1.路径导航<!doctypehtml><html><head><metacharset="utf-8"><title>路径导航<itle><linkrel="stylesheet"type="text/css"href="css/bootstrap.min.css"><scripttype="text/ja
问题描述:最近在学习BootStrap,过程中遇到引用glyphicon图标无法显示的问题,经过在百度后该问题已解决。1、首先看一下图标显示失败的页面:2、经过参考大佬们的经验,我找到了解决办法。首先我的BootStrap的css样式表是经过下载之后直接拷贝了其中一个文件到编译器中使用的,没有把所有
BootStrap布局一、BootStrap布局CSS组件主要包括栅格系统、列表组、进度条、icon图标、导航栏等组件。JavaScript插件主要有动画效果、窗体模式、下拉菜单、选项卡等二、网格系统Bootstrap内置了一套响应式、移动优先的流式栅格系统,随着屏幕设备或可视窗口(viewport)尺寸的
1引入所需要的文件2用法
想让bootstrap的table列内容超出部分省略号,要在table上加table-layout:fixed和word-break:break-all,然后在头部thead的th加上宽度百分比,最后在列里加个标签如span,在这个span加上单行超出部分省略号的css:display:inline-block,overflow:hidden,white-space:nowrap,text-overflow:e