订单管理
表结构设计
编辑myproject/employee_management/models.py
class Order(models.Model):
""" 订单 """
oid = models.CharField(verbose_name="订单号", max_length=64)
title = models.CharField(verbose_name="名称", max_length=32)
price = models.IntegerField(verbose_name="价格")
status_choices = (
(1, "待支付"),
(2, "已支付"),
)
status = models.SmallIntegerField(verbose_name="状态", choices=status_choices, default=1)
admin = models.ForeignObject(verbose_name="管理员", to="Admin", on_delete=models.CASCADE)
生成数据库表
python3 manage.py makemigrations
python3 manage.py migrate
订单添加
首先实现弹出对话框
编辑myproject/myproject/urls.py
# 订单管理
path('order/list/', order.order_list)
新建myproject/employee_management/views/order.py
from django.shortcuts import render
def order_list(request):
return render(request, 'order_list.html')
新建myproject/employee_management/templates/order_list.html
{% extends 'layout.html' %}
{% block content %}
<div class="container">
<div>
<input type="button" value="新建订单1" class="btn btn-primary" data-toggle="modal" data-target="#myModal">
<input id="btnAdd" type="button" value="新建订单2" class="btn btn-primary">
</div>
</div>
<!-- 新建订单1 - 对话框 -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">Modal title</h4>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
{% endblock %}
{% block script %}
<script type="text/javascript">
$(function(){
bindBtnAddEvent();
})
function bindBtnAddEvent(){
$("#btnAdd").click(function(){
$("#myModal").modal('show');
});
}
</script>
{% endblock %}
- 第一种方式: 官网自带方式
- 第二种方式: javascript实现
{% block script %}
<script type="text/javascript">
$(function(){
bindBtnAddEvent();
})
function bindBtnAddEvent(){
$("#btnAdd").click(function(){
$("#myModal").modal('show');
});
}
</script>
{% endblock %}
编辑myproject/employee_management/templates/layout.html
<li><a href="/order/list/">订单管理</a></li>
浏览器访问
接下来编辑弹窗里的内容
编辑myproject/employee_management/views/order.py
from employee_management.utils.modelform import BootStrapModelForm
class OrderModelForm(BootStrapModelForm):
class Meta:
model = models.Order
# fields = "__all__"
# 排除 oid 订单号,让系统自动生成
# 排除 admin 管理员, 默认使用当前登录用户为管理员
exclude = ["oid", "admin"]
def order_list(request):
form = OrderModelForm()
return render(request, 'order_list.html', {"form": form})
编辑myproject/employee_management/templates/order_list.html
<form method="post" id="formSave" novalidate>
<div>
{% for item in form %}
<div class="col-xs-6">
<div class="form-group" style="position: relative; margin-top: 5px">
<label>{{ item.label }}</label>
{{ item }}
<span class="error_msg" style="color: red;position: absolute;"></span>
</div>
</div>
{% endfor %}
</div>
</form>
浏览器访问测试
接下来实现数据的提交
编辑myproject/employee_management/templates/order_list.html
function bindBtnSaveEvent(){
$("#btnSave").click(function(){
// 清除错误信息
$(".error_msg").empty();
$.ajax({
url: "/order/add/",
type: "post",
data: $("#formSave").serialize(),
dataType: "JSON",
success: function(res) {
if(res.status){
alert("创建订单成功");
} else {
$.each(res.error, function(name, errorlist){
$("#id_" + name).next().text(errorlist[0]);
})
}
}
})
});
编辑myproject/employee_management/views/order.py
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def order_add(request):
""" 新建订单 """
form = OrderModelForm(data=request.POST)
if form.is_valid():
form.save()
return HttpResponse(json.dumps({"status": True}))
return HttpResponse(json.dumps({"status": False, "error": form.errors}))
浏览器进行测试
优化弹出窗口:
- 自动生成订单号
- 使用当前登录用户为订单管理员
- 添加完成后自动关闭弹出的窗口
编辑myproject/employee_management/templates/order_list.html
function bindBtnSaveEvent(){
$("#btnSave").click(function(){
// 清除错误信息
$(".error_msg").empty();
$.ajax({
url: "/order/add/",
type: "post",
data: $("#formSave").serialize(),
dataType: "JSON",
success: function(res) {
if(res.status){
alert("创建订单成功");
// 清空表单
$("#formSave")[0].reset();
// 关闭对话框
$("#myModal").modal('hide');
} else {
$.each(res.error, function(name, errorlist){
$("#id_" + name).next().text(errorlist[0]);
})
}
}
})
});
}
编辑myproject/employee_management/views/order.py
from datetime import datetime
from random import randint
class OrderModelForm(BootStrapModelForm):
class Meta:
model = models.Order
# fields = "__all__"
# 排除 oid 订单号,让系统自动生成
# 排除 admin 管理员, 默认使用当前登录用户为管理员
exclude = ["oid", "admin"]
@csrf_exempt
def order_add(request):
""" 新建订单 """
form = OrderModelForm(data=request.POST)
if form.is_valid():
# 增加 oid 订单号
form.instance.oid = datetime.now().strftime("%Y%m%d%H%M%S") + str(randint(1000,9000))
# 设置当前登录用户为订单的管理员
admin_user = request.session["info"]["id"]
print(admin_user)
form.instance.admin_id = admin_user
form.save()
return HttpResponse(json.dumps({"status": True}))
return HttpResponse(json.dumps({"status": False, "error": form.errors}))
浏览器访问测试
订单列表
首先实现订单列表的数据展示和分页搜索
编辑myproject/employee_management/views/order.py
def order_list(request):
form = OrderModelForm()
##########################################################
# >>>>>生成页码与搜索
data_dict = {}
search_data = request.GET.get('query', "")
# title__ccontains 表示使用title作为搜索字段进行内容匹配
if search_data:
data_dict["title__contains"] = search_data
# 对搜索内容进行查询,为空表示获取所有数据
queryset = models.Order.objects.filter(**data_dict).order_by('-id')
page_object = Pagination(request, queryset, page_size=10, page_param="page")
page_queryset = page_object.page_queryset
# 调用对象的html方法,生成页码
page_object.html()
page_string = page_object.page_string
##########################################################
context = {
"queryset": page_queryset,
"form": form,
"page_string": page_string,
"search_data": search_data,
}
return render(request, 'order_list.html', context)
编辑myproject/employee_management/templates/order_list.html
<div class="container">
<div style="margin-bottom: 20px;">
<input type="button" value="新建订单1" class="btn btn-primary" data-toggle="modal" data-target="#myModal">
<input id="btnAdd" type="button" value="新建订单2" class="btn btn-primary">
</div>
<div>
<div class="panel panel-default">
<!-- Default panel contents -->
<div class="panel-heading">
<span class="glyphicon glyphicon-th-list" aria-hidden="true" style="margin-right: 5px;"></span>
<span>订单列表</span>
</div>
<!-- Table -->
<table class="table table-bordered">
<thead>
<tr>
<th>ID</th>
<th>订单号</th>
<th>名称</th>
<th>价格</th>
<th>状态</th>
<th>管理员</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for obj in queryset %}
<tr>
<th>{{ obj.id }}</th>
<th>{{ obj.oid }}</th>
<th>{{ obj.title }}</th>
<td>{{ obj.price }}</td>
<td>{{ obj.get_status_display }}</td>
<td>{{ obj.admin.username }}</td>
<td>
<a class="btn btn-primary btn-xs" href="#">编辑</a>
<a class="btn btn-danger btn-xs" href="#">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<ul class="pagination">
{{ page_string }}
</ul>
<br>
<form method="get">
<div style="display:inline-block; width: 150px;">
<div class="input-group">
<span> <input type="text" class="form-control" placeholder="请输入页码" name="page"></span>
<span class="input-group-btn">
<button class="btn btn-primary" type="submit">跳转</button>
</span>
</div>
</div>
</form>
</div>
<!-- 新建订单 - 对话框 -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">新建订单</h4>
</div>
<div class="modal-body">
<form method="post" id="formSave" novalidate>
<div>
{% for item in form %}
<div class="col-xs-6">
<div class="form-group" style="position: relative; margin-top: 5px">
<label>{{ item.label }}</label>
{{ item }}
<span class="error_msg" style="color: red;position: absolute;"></span>
</div>
</div>
{% endfor %}
</div>
</form>
</div>
<div class="modal-footer bottom-right" style="margin-top: 250px;">
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" id="btnSave">保存</button>
</div>
</div>
</div>
</div>
添加新订单后,让页面自动刷新
// 刷新页面
location.reload();
浏览器刷新
订单删除
目标:
实现点击删除
按钮后,弹出确认删除
的弹出框,确认
后再进行删除
编辑myproject/employee_management/templates/order_list.html
,实现点击删除
按钮后,弹出确认删除
的对话框
<!-- 删除 对话框 -->
<div class="modal fade" id="myModalDelete" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-body">
<div class="alert alert-danger alert-dismissible fade in" role="alert">
<h4>是否确定删除?</h4>
<p>删除后所有关联的相关数据都将被删除</p>
<p>
<button id="btnConfirmDelete" type="button" class="btn btn-danger">确定</button>
<!-- data-dismiss="modal" 表示点击取消按钮后,关闭对话框 -->
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
</p>
</div>
</div>
</div>
</div>
下面是用 js 和 ajax的方式实现数据行的删除,注意下面的id与class绑定匹配, 例如:
$(".btn-delete")
对应HTML中的class="btn-delete"
位置
$("#btnConfirmDelete")
对应HTML中的id="btnConfirmDelete"
位置
{% block script %}
<script type="text/javascript">
var DELETE_ID;
$(function () {
bindBtnAddEvent();
bindBtnSaveEvent();
bindBtnDeleteEvent();
bindBtnConfirmDeleteEvent();
})
function bindBtnAddEvent() {
$("#btnAdd").click(function () {
$("#myModal").modal('show');
});
}
function bindBtnSaveEvent() {
$("#btnSave").click(function () {
// 清除错误信息
$(".error_msg").empty();
$.ajax({
url: "/order/add/",
type: "post",
data: $("#formSave").serialize(),
dataType: "JSON",
success: function (res) {
if (res.status) {
alert("创建订单成功");
// 清空表单
$("#formSave")[0].reset();
// 关闭对话框
$("#myModal").modal('hide');
// 刷新页面
location.reload();
} else {
$.each(res.error, function (name, errorlist) {
$("#id_" + name).next().text(errorlist[0]);
})
}
}
})
});
}
function bindBtnDeleteEvent() {
$(".btn-delete").click(function () {
// 显示删除对话框
$("#myModalDelete").modal('show');
//获取当前行的ID
DELETE_ID = $(this).attr("uid");
});
}
function bindBtnConfirmDeleteEvent(){
$("#btnConfirmDelete").click(function(){
// 点击确认删除按钮,将全局变量中设置的那个要删除的ID发送到后台
$.ajax({
url: "/order/delete/", // => /order/delete/?uid=123
type: "GET",
dataType: "JSON",
data: {
uid: DELETE_ID
},
success: function(res) {
if(res.status) {
// alert("删除成功");
//隐藏删除框
// $("#myModalDelete").modal("hide");
//删除列表中的那一行
// $("tr[uid='" + DELETE_ID + "']").remove();
//将要删除的DELETE_ID置空
// DELETE_ID = 0;
//刷新页面列表
location.reload();
} else {
alert(res.error);
}
}
})
});
}
</script>
{% endblock %}
location.reload();
表示删除完成后,让页面自动刷新
它上面注释掉的那一段,可以实现删除后,让页面删除的那一行清除,但是会有一个问题,第二页的数据不会顶上来,也就是说当前页面有 10 行数据,我们删除一行后,只剩下 9 行数据,不会自动刷新
编辑myproject/myproject/urls.py
path('order/delete/', order.order_delete),
编辑myproject/employee_management/views/order.py
def order_delete(request):
""" 删除订单 """
uid = request.GET.get('uid')
# 判断获取到的 id 数据行是否存在
if models.Order.objects.filter(id=uid).exists():
models.Order.objects.filter(id=uid).delete()
return HttpResponse(json.dumps({"status": True}))
else:
return HttpResponse(json.dumps({"status": False, "error": "删除失败, 数据不存在,请刷新页面后重试!"}))
浏览器测试
订单编辑
这个逻辑稍微复杂一些,慢慢理解
编辑myproject/employee_management/templates/order_list.html
{% extends 'layout.html' %}
{% block content %}
<div class="container">
<div style="margin-bottom: 20px;">
<input type="button" value="新建订单1" class="btn btn-primary" data-toggle="modal" data-target="#myModal">
<input id="btnAdd" type="button" value="新建订单2" class="btn btn-primary">
</div>
<div>
<div class="panel panel-default">
<!-- Default panel contents -->
<div class="panel-heading">
<span class="glyphicon glyphicon-th-list" aria-hidden="true" style="margin-right: 5px;"></span>
<span>订单列表</span>
</div>
<!-- Table -->
<table class="table table-bordered">
<thead>
<tr>
<th>ID</th>
<th>订单号</th>
<th>名称</th>
<th>价格</th>
<th>状态</th>
<th>管理员</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for obj in queryset %}
<tr uid="{{ obj.id }}">
<th>{{ obj.id }}</th>
<th>{{ obj.oid }}</th>
<th>{{ obj.title }}</th>
<td>{{ obj.price }}</td>
<td>{{ obj.get_status_display }}</td>
<td>{{ obj.admin.username }}</td>
<td>
<input uid="{{ obj.id }}" class="btn btn-primary btn-xs btn-edit" type="button" value="编辑">
<input uid="{{ obj.id }}" class="btn btn-danger btn-xs btn-delete" type="button" value="删除"
data-dismiss="alert" aria-label="Close">
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<ul class="pagination">
{{ page_string }}
</ul>
<br>
<form method="get">
<div style="display:inline-block; width: 150px;">
<div class="input-group">
<span> <input type="text" class="form-control" placeholder="请输入页码" name="page"></span>
<span class="input-group-btn">
<button class="btn btn-primary" type="submit">跳转</button>
</span>
</div>
</div>
</form>
</div>
<!-- 新建/编辑 订单 对话框 -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="myModalLabel">新建订单</h4>
</div>
<div class="modal-body">
<form method="post" id="formSave" novalidate>
<div>
{% for item in form %}
<div class="col-xs-6">
<div class="form-group" style="position: relative; margin-top: 5px">
<label>{{ item.label }}</label>
{{ item }}
<span class="error_msg" id="error_msg" style="color: red;position: absolute;"></span>
</div>
</div>
{% endfor %}
</div>
</form>
</div>
<div class="modal-footer bottom-right" style="margin-top: 150px;">
<button type="button" class="btn btn-default" data-dismiss="modal" id="btn-cancel">取消</button>
<button type="button" class="btn btn-primary" id="btnSave">保存</button>
</div>
</div>
</div>
</div>
<!-- 删除 对话框 -->
<div class="modal fade" id="myModalDelete" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-body">
<div class="alert alert-danger alert-dismissible fade in" role="alert">
<h4>是否确定删除?</h4>
<p>删除后所有关联的相关数据都将被删除</p>
<p>
<button id="btnConfirmDelete" type="button" class="btn btn-danger">确定</button>
<!-- data-dismiss="modal" 表示点击取消按钮后,关闭对话框 -->
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
</p>
</div>
</div>
</div>
</div>
{% endblock %}
{% block script %}
<script type="text/javascript">
var DELETE_ID;
var EDIT_ID;
$(function () {
bindBtnAddEvent();
bindBtnSaveEvent();
bindBtnDeleteEvent();
bindBtnConfirmDeleteEvent();
bindBtnEditEvent();
})
function bindBtnAddEvent() {
$("#btnAdd").click(function () {
// 将正在编辑的 ID 设置为空
EDIT_ID = undefined;
// 添加前先将对话框内容清空
$("#formSave")[0].reset();
// 修改标题
$("#myModalLabel").text('新建');
// 显示对话框
$("#myModal").modal('show');
});
}
function bindBtnSaveEvent() {
$("#btnSave").click(function () {
// 清除错误信息
$(".error_msg").empty();
if (EDIT_ID) {
// 编辑
doEdit();
} else {
// 添加
doAdd();
}
});
}
function doAdd() {
$.ajax({
url: "/order/add/",
type: "post",
data: $("#formSave").serialize(),
dataType: "JSON",
success: function (res) {
if (res.status) {
alert("创建订单成功");
// 清空表单
$("#formSave")[0].reset();
// 关闭对话框
$("#myModal").modal('hide');
// 刷新页面
location.reload();
} else {
$.each(res.error, function (name, errorlist) {
$("#id_" + name).next().text(errorlist[0]);
})
}
}
})
}
function doEdit() {
$.ajax({
url: "/order/edit/?uid=" + EDIT_ID,
type: "post",
data: $("#formSave").serialize(),
dataType: "JSON",
success: function (res) {
if (res.status) {
// 清空表单
$("#formSave")[0].reset();
// 关闭对话框
$("#myModal").modal('hide');
// 刷新页面
location.reload();
} else {
if (res.tips) {
alert(res.tips)
} else {
$.each(res.error, function (name, errorlist) {
$("#id_" + name).next().text(errorlist[0]);
})
}
}
}
})
}
function bindBtnDeleteEvent() {
$(".btn-delete").click(function () {
// 显示删除对话框
$("#myModalDelete").modal('show');
//获取当前行的ID
DELETE_ID = $(this).attr("uid");
});
}
function bindBtnConfirmDeleteEvent() {
$("#btnConfirmDelete").click(function () {
// 点击确认删除按钮,将全局变量中设置的那个要删除的ID发送到后台
$.ajax({
url: "/order/delete/", // => /order/delete/?uid=123
type: "GET",
dataType: "JSON",
data: {
uid: DELETE_ID
},
success: function (res) {
if (res.status) {
// alert("删除成功");
//隐藏删除框
// $("#myModalDelete").modal("hide");
//删除列表中的那一行
// $("tr[uid='" + DELETE_ID + "']").remove();
//将要删除的DELETE_ID置空
// DELETE_ID = 0;
//刷新页面列表
location.reload();
} else {
alert(res.error);
}
}
})
});
}
function bindBtnEditEvent() {
$(".btn-edit").click(function () {
// 清除错误信息
$(".error_msg").empty();
var uid = $(this).attr("uid");
EDIT_ID = uid;
// 发送 Ajax 去后台获取当前行的相关数据
$.ajax({
url: "/order/detail/",
type: "GET",
data: {
uid: uid
},
dataType: "JSON",
success: function (res) {
if (res.status) {
// 添加前先将对话框内容清空
$("#formSave")[0].reset();
// 展示当前行的数据
$.each(res.data, function (name, value) {
$("#id_" + name).val(value);
});
// 更改标题
$("#myModalLabel").text('编辑');
// 显示对话框
$("#myModal").modal('show');
} else {
alert(res.error);
}
}
});
})
}
</script>
{% endblock %}
在上面的代码中,进行了如下方面的操作:
- 编辑和新建订单共用一个对话框,使用
doEdit
和doAdd
进行区分 - 编辑页面中自动填充已有数据
- 编辑的js代码分为
bindBtnEditEvent()
与doEdit()
- 编辑对话框中保存时,需要考虑到当前的数据行是否存在
编辑myproject/employee_management/views/order.py
def order_detail(request):
""" 根据id获取订单详情 """
uid = request.GET.get('uid')
row_object = models.Order.objects.filter(id=uid).values("title", "price", "status").first()
if not row_object:
return HttpResponse(json.dumps({"status": False, "error": "数据不存在!"}))
# 从数据库中获取到一个对象 row_object
result = {
"status": True,
"data": row_object,
}
return HttpResponse(json.dumps(result))
@csrf_exempt
def order_edit(request):
""" 编辑订单 """
uid = request.GET.get('uid')
row_object = models.Order.objects.filter(id=uid).first()
if not row_object:
return HttpResponse(json.dumps({"status": False, "tips": "数据不存在!"}))
# 获取编辑界面提交的数据
data = request.POST
# 判断编辑的内容是否跟以前一样
if data["title"] != '' and data['price'] != '' and data['status'] != '':
flag = 0
if row_object.title == data["title"]:
flag += 1
if row_object.price == int(data["price"]):
flag += 1
if row_object.status == int(data["status"]):
flag += 1
# 如果输入的内容与原有内容相同,则进行提示
if flag == 3:
return HttpResponse(json.dumps({"status": False, "tips": "您没有变更任何内容,无需修改!"}))
form = OrderModelForm(data=request.POST, instance=row_object)
if form.is_valid():
form.save()
return HttpResponse(json.dumps({"status": True}))
return HttpResponse(json.dumps({"status": False, "error": form.errors}))
编辑myproject/myproject/urls.py
path('order/detail/', order.order_detail),
path('order/edit/', order.order_edit),
浏览器进行测试
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/100694.html