有些列表数据需要删除,但是又不能做到点击后直接删除,因为这样容易导致误删,所以需要提供二次确定提示框,用户点击确定删除后,逻辑删除数据。点击取消或x后,取消删除操作。
方法一:通过模态框来实现
employee_mange.py
<!--用户列表表单-->
<div class="row" style="padding-top: 10px; width: 100%">
<div class="col-md-12">
<table class="table table-striped">
<thead>
<tr>
<th>id</th><th>姓名</th><th>职能</th><th>状态</th><th>操作</th>
</tr>
</thead>
<tbody>
{
% for employee in employees %}
<tr>
<td>{
{
employee.id}}</td>
<td>{
{
employee.name}}</td>
<td>{
{
employee.type}}</td>
<td>{
{
employee.del_status}}</td>
<td>
<a href="/index/{
{employee.id}}/" target="{
{employee.id}}_blank">修改</a>
<!-- 删除操作触发模态框 -->
<a href="#" onclick="del_employee({
{employee.id}})">删除</a>
</td>
</tr>
{
% endfor %}
</tbody>
</table>
</div>
</div>
追加同一个页面,针对删除操作的脚本语句
<script type="text/javascript">
$("#delEmployeeModal").modal("hide");//加载页面首先隐藏模态框,指向模态框的ID
function del_employee(emp_id){
$("#delEmployeeModal").modal("show");//显示模态框
$('#employee_id').val(emp_id);
<!-- alert("你即将删除用户"+emp_id)-->
}
</script>
<script type="text/javascript">
$("#del_id").click(function(){
var eID = $("#employee_id").val();
javascript:location.href='/employee_del_action/'+eID;
})
</script>
以上为用户列表页面代码
views.py
# 删除用户
@login_required
def employee_del_action(request, employee_id):
result = Employee.objects.filter(id=employee_id)
if not result:
return render(request, 'employee_manage.html', {
'employee.name': result.name, 'hint': '该用户不存在'})
result = Employee.objects.filter(id=employee_id, del_status=1)
if result:
return render(request, 'employee_manage.html', {
'employee.name': result.name, 'hint': '该用户已被删除,请勿重复操作'})
else:
Employee.objects.select_for_update().filter(id=employee_id).update(del_status=1)
response = HttpResponseRedirect('/employee_manage/')
return response
以上views.py中描述的删除用户的函数中,提示语句暂时未能实现。目前方法一只能实现正常删除数据。
添加路由地址
url.py
"""ManagerPlan URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/2.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, re_path
from plan import views
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', views.index), # 添加index路径配置
path('employee_manage/', views.employee_manage), # 添加角色列表路径
path('plan/', views.plan), # 添加图片路径配置
path('login_action/', views.login_action), # 添加登录跳转路径配置
path('plan_manage/', views.plan_manage), # 添加计划管理路径配置
path('account/login/', views.index), # 添加访问非登录页面时,指引跳转到登录路径配置
path('search_content/', views.search_content), # 查询内容路径
path('search_employee/', views.search_employee), # 查询用户路径
path('employee_add/', views.employee_add), # 新增用户页面路径
path('employee_add_action/', views.employee_add_action), # 新增用户路径
path('content_tag/', views.content_tag), # 退出
re_path('employee_del_action/(?P[0-9]+)/' , views.employee_del_action), # 新增用户路径
path('logout/', views.logout), # 退出
]
用正则法匹配,一直无法匹配到正确到地址,发现,原来用path是行不通到,要引入re_path
re_path(‘employee_del_action/(?P
实现效果如下:
拓展:
如果遇上路径和转换器语法都不足以定义的URL模式,那么就需要使用正则表达式,这时候就需要使用re_path(),而非path()。
举例:传递 数字结尾的参数
re_path(r'(\d+)/$',views.peopleList,name='peopleList'),
python正则表达式可详见这篇文章:Python系列之正则表达式详解
方法二:通过ajax来处理删除操作
参考文章:Django实现文章删除功能
ajax url 路径写法
layer关闭弹窗(多种关闭弹窗方法)
plan_manage.html
<head>
<meta charset="utf-8">
{
% load bootstrap3 %}
{
% bootstrap_css %}
{
% bootstrap_javascript %}
<title> 计划管理系统</title>
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script type="text/javascript" src="/static/js/layer/layer.js"></script>
</head>
<!--............ 中间省略,以下为body里面的内容-->
<!--需求列表表单-->
<div class="row" style="padding-top: 10px; width: 100%">
<div class="col-md-12">
<table class="table table-striped">
<thead>
<tr>
<th>id</th><th>需求</th><th>优先级</th><th>测试</th><th>开发</th><th>需求</th>
<th>期望上线</th><th>上线时间</th><th>状态</th><th>项目</th><th>删除状态</th><th>创建时间</th><th>修改时间</th>
<th>备注</th><th>操作</th>
<!-- <th>url</th>-->
</tr>
</thead>
<tbody>
{
% for requirement in requirements %}
<tr>
<td>{
{
requirement.id}}</td>
<td>{
{
requirement.content}}</td>
<td>{
{
requirement.emergenyLevel}}</td>
<td>{
{
requirement.tester}}</td>
<td>{
{
requirement.dever}}</td>
<td>{
{
requirement.requirer}}</td>
<td>{
{
requirement.expentedTime}}</td>
<td>{
{
requirement.onlineTime}}</td>
<td>{
{
requirement.online_status}}</td>
<td>{
{
requirement.project}}</td>
<td>{
{
requirement.del_status}}</td>
<!-- <td>{
{
requirement.url}}</td>-->
<td>{
{
requirement.create_time}}</td>
<td>{
{
requirement.update_time}}</td>
<td>{
{
requirement.remarks}}</td>
<td>
<a href="/index/{
{employee.id}}/" target="{
{employee.id}}_blank">详情</a>
<a href="/index/{
{employee.id}}/" target="{
{employee.id}}_blank">修改</a>
<a href="#" onclick="del_requirement(this, {
{requirement.id}})">删除</a>
</td>
</tr>
{
% endfor %}
</tbody>
</table>
</div>
</div>
追加与上述同个页面,删除操作的脚本处理
<script>
function del_requirement(the, requirement_id){
var article_name = $(the).parents("tr").children("td").eq(1).text();
var index =layer.open({
type: 1,
skin: "layui-layer-rim",
area: ["400px", "200px"],
title: "删除需求",
content: '删除内容:《'+article_name+'》
',
btn:['确定', '取消'],
yes: function(){
layer.close(index);
$.ajax({
url: '/requirement_del_action/',
type:"POST",
data: {
"requirement_id":requirement_id},
success: function(e){
if (e=="1")
{
<!-- 不知道为什么提示语一闪而过,想要提示语提示2秒后隐藏,刷新页面-->
layer.msg("删除成功", {
icon: 6, time: 2000} ,function(){
parent.location.reload();
});
}
else if (e=="2")
{
layer.msg("删除失败", {
icon: 6, time: 2000} ,function(){
parent.location.reload();
});
}
else if (e=="3")
{
layer.msg("该内容不存在", {
icon: 6, time: 2000} ,function(){
parent.location.reload();
});
}
else if (e=="4")
{
layer.msg("该内容已被删除,请不要重复操作", {
icon: 6, time: 2000} ,function(){
parent.location.reload();
});
}
else
{
layer.msg("系统异常");
}
},
})
},
});
}
</script>
需要在views.py添加视图函数。
views.py
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST
# .......中间部分其他内容省略
@login_required
@require_POST
@csrf_exempt
def requirement_del_action(request):
requirement_id = request.POST['requirement_id']
result = Requirement.objects.get(id=requirement_id)
if not result:
return HttpResponse("3")
result = Requirement.objects.filter(id=requirement_id, del_status=1)
if result:
return HttpResponse("4")
else:
try:
Requirement.objects.select_for_update().filter(id=requirement_id).update(del_status=1)
return HttpResponse("1")
except:
return HttpResponse("2")
在urls.py中添加:
path(‘requirement_del_action/’, views.requirement_del_action), # 删除需求内容路径
urls.py
from django.contrib import admin
from django.urls import path, re_path
from plan import views
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', views.index), # 添加index路径配置
path('employee_manage/', views.employee_manage), # 添加角色列表路径
path('plan/', views.plan), # 添加图片路径配置
path('login_action/', views.login_action), # 添加登录跳转路径配置
path('plan_manage/', views.plan_manage), # 添加计划管理路径配置
path('requirement_add/', views.requirement_add), # 增加需求页面路径
path('requirement_add_action/', views.requirement_add_action), # 增加需求内容路径配置
path('account/login/', views.index), # 添加访问非登录页面时,指引跳转到登录路径配置
path('search_content/', views.search_content), # 查询内容路径
path('search_employee/', views.search_employee), # 查询用户路径
path('employee_add/', views.employee_add), # 新增用户页面路径
path('employee_add_action/', views.employee_add_action), # 新增用户路径
path('content_tag/', views.content_tag), # 退出
re_path('employee_del_action/(?P[0-9]+)/' , views.employee_del_action), # 新增用户路径
path('requirement_del_action/', views.requirement_del_action), # 删除需求内容路径
re_path('requirement_detail/(?P[0-9]+)/' , views.employee_del_action), # 新增用户路径
path('logout/', views.logout), # 退出
]
遇到的问题:
问题1、Uncaught ReferenceError: layer is not defined
解决办法:缺少js的引入(js/layer.js)
直接下载layer.js,然后在当前要使用的项目中引入
在settings.py中添加js
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.1/howto/static-files/
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATICFILES_DIRS = (
('css', os.path.join(STATIC_ROOT, 'css').replace('\\', '/')),
('js', os.path.join(STATIC_ROOT, 'js').replace('\\', '/')),
('images', os.path.join(STATIC_ROOT, 'images').replace('\\', '/')),
)
记得重启项目
python3 manage.py runserver
并清除浏览器缓存,重新访问。
删除参考:
https://blog.csdn.net/chengqiuming/article/details/85310298
问题2:
如何获取要删除的内容标题?
方法如下:
var article_name = $(the).parents("tr").children("td").eq(1).text();
title: "删除需求",
content: '删除内容:《'+article_name+'》
',
btn:['确定', '取消'],
问题3:
layer.msg不知道为什么提示语一闪而过,想要提示语提示2秒后隐藏,刷新页面
1)、如何在点击确定的时候,就隐藏layer
将layer.open打开后的索引赋值给某个变量,然后通过layer.close(index)的方法关闭。
2)、如何让提示语在2s后消失,并且自动刷新页面
在plan_manage.py中涉及删除操作的script脚本中按此处理(详见以上具体代码)
layer.msg("删除成功", {
icon: 6, time: 2000} ,function(){
parent.location.reload();
});
接下来,要处理:如何实现点击【详情】展示内容详情。
参考文章:Django实现点击详情跳转新界面、路由名称和分发3