sweetalert弹窗
# 通过sweetalert实现删除数据时触发弹窗, 确认是否删除
def home(request):
user_queryset = models.User.objects.all()
if request.is_ajax():
back_dic = {'code': 1000, 'msg': ''}
print(request.POST)
delete_id = int(request.POST.get('delete_id')[0])
time.sleep(2)
models.User.objects.filter(pk=delete_id).delete()
back_dic['msg'] = 'Data has been deleted'
return JsonResponse(back_dic)
return render(request, 'home.html', locals())
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
{% load static %}
<script src="{% static 'JQuery-3.4.1/JQuery.js' %}"></script>
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
<script src="{% static 'bootstrap-sweetalert-master/dist/sweetalert.min.js' %}"></script>
<link rel="stylesheet" href="{% static 'bootstrap-sweetalert-master/dist/sweetalert.css' %}">
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
</head>
<body>
<div class="container">
<div class="row"></div>
<div class="col-md-8 col-md-offset-2">
<h1 class="text-center">User Info</h1>
<table class="table table-hover table-bordered table-striped">
<thead>
<tr>
<th>NO.</th>
<th>Username</th>
<th>Age</th>
<th>Gender</th>
<th class="text-center">Actions</th>
</tr>
</thead>
<tbody>
{% for user in user_queryset %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ user.username }} </td>
<td>{{ user.age }} </td>
<td>{{ user.get_gender_display }} </td>
<td class="text-center">
<a href="#" class="btn btn-primary btn-sm">Edit</a>
{#给a标签加一个cancel类以便定位到该标签#}
<a href="#" class="btn btn-danger btn-sm cancel" id={{ user.pk }}>Delete</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<script>
$(".cancel").click(function () {
let $btn = $(this);
swal({
title: "Are you sure?",
text: "You will not be able to recover this imaginary file!",
type: "warning",
showCancelButton: true,
confirmButtonClass: "btn-danger",
confirmButtonText: "Yes, delete it!",
cancelButtonText: "No, cancel plx!",
closeOnConfirm: false,
closeOnCancel: false,
showLoaderOnConfirm: true
},
function (isConfirm) {
if (isConfirm) {
$.ajax({
url: "",
type: "post",
data: {"delete_id": $btn.attr('id')},
success: function (data) {
if (data.code==1000) {
swal("Deleted!", "Data has been deleted.", "success");
{#通过DOM操作直接将删除的标签移除#}
$btn.parent().parent().remove()
} else {
swal("Error", "Unknown error", "warning");
}
}
});
} else {
swal("Cancelled", "Data delete has been cancelled :)", "error");
}
})
});
</script>
</body>
</html>
bulk-create
- 用于向数据库中批量添加数据
- 先将数据对象都添加到列表中, 然后将该列表传给bulk_create方法
# 这样向数据库添加大量数据速度非常慢, 甚至会导致程序崩溃
for i in range(10000):
models.Book.objects.create(title=f'book-{i}')
# 使用bulk_create方法可快速向数据库中添加大量数据对象
lis = []
for i in range(10000):
obj = models.Book(title=f'book-{i}')
lis.append(obj)
models.Book.objects.bulk_create(lis)
自定义分页器
- queryset对象支持切片操作
- 可以直接向html文件发送html代码(字符串格式)
# 实现简单的分页展示效果
def index(request):
# 分页器一次展示的页数为 page_controller * 2 + 1
page_controller = 3
if page_controller < 1:
page_controller = 1
# 数据库图书个数
book_num = models.Book.objects.all().count()
per_page_num = 5
# 判断一共有多少页
page_num, more = divmod(book_num, per_page_num)
if more:
page_num += 1
# 获取当前页数, 设置默认值为1
page_init = int(request.GET.get('page', 1))
page = page_init
# 防止分页器末尾超出总页数
if page_init > page_num - page_controller:
page = page_num - page_controller
# 防止分页器开头出现0或负数页
if page_init < page_controller + 1:
page = page_controller + 1
# 切片操作的起始和结束位置
page_start = (page_init - 1) * per_page_num
page_end = page_init * per_page_num
# 切片获取当前页数对应的图书数据
book_queryset = models.Book.objects.all()[page_start: page_end]
# 直接向html文件发送html代码
html = ''
for i in range(page - page_controller, page + page_controller + 1):
# 当前页标签高亮
if i == page_init:
html += f'<li class="active"><a href="?page={i}">{i}</a></li>'
else:
html += f'<li><a href="?page={i}">{i}</a></li>'
return render(request, 'index.html', locals())
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
{% load static %}
<script src="{% static 'JQuery-3.4.1/JQuery.js' %}"></script>
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h1 class="text-center">Book List</h1>
<table class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th>NO.</th>
<th>Book Title</th>
</tr>
</thead>
<tbody>
{% for book in book_queryset %}
<tr>
<td>{{ book.pk }}</td>
<td>{{ book.title }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="text-center">
<nav aria-label="Page navigation">
<ul class="pagination">
{{ html|safe }}
</ul>
</nav>
</div>
</div>
</div>
</div>
</body>
</html>
- 第三方分页器的使用
- 在app文件夹或者总项目文件夹下, 新建utils文件夹, 将下面分页文件放到utils文件下
- 两个参数:
current_page
和 all_count
- 将html代码字符串封装到了
pagination_obj.page_html
中
# Pagination.py
class Pagination(object):
def __init__(self,current_page,all_count,per_page_num=10,pager_count=5):
"""
封装分页相关数据
:param current_page: 当前页
:param all_count: 数据库中的数据总条数
:param per_page_num: 每页显示的数据条数
:param pager_count: 最多显示的页码个数
用法:
queryset = model.objects.all()
page_obj = Pagination(current_page,all_count)
page_data = queryset[page_obj.start:page_obj.end]
获取数据用page_data而不再使用原始的queryset
获取前端分页样式用page_obj.page_html
"""
try:
current_page = int(current_page)
except Exception as e:
current_page = 1
if current_page <1:
current_page = 1
self.current_page = current_page
self.all_count = all_count
self.per_page_num = per_page_num
# 总页码
all_pager, tmp = divmod(all_count, per_page_num)
if tmp:
all_pager += 1
self.all_pager = all_pager
self.pager_count = pager_count
self.pager_count_half = int((pager_count - 1) / 2)
@property
def start(self):
return (self.current_page - 1) * self.per_page_num
@property
def end(self):
return self.current_page * self.per_page_num
def page_html(self):
# 如果总页码 < 11个:
if self.all_pager <= self.pager_count:
pager_start = 1
pager_end = self.all_pager + 1
# 总页码 > 11
else:
# 当前页如果<=页面上最多显示11/2个页码
if self.current_page <= self.pager_count_half:
pager_start = 1
pager_end = self.pager_count + 1
# 当前页大于5
else:
# 页码翻到最后
if (self.current_page + self.pager_count_half) > self.all_pager:
pager_end = self.all_pager + 1
pager_start = self.all_pager - self.pager_count + 1
else:
pager_start = self.current_page - self.pager_count_half
pager_end = self.current_page + self.pager_count_half + 1
page_html_list = []
# 添加前面的nav和ul标签
page_html_list.append('''
<nav aria-label='Page navigation>'
<ul class='pagination'>
''')
first_page = '<li><a href="?page=%s">首页</a></li>' % (1)
page_html_list.append(first_page)
if self.current_page <= 1:
prev_page = '<li class="disabled"><a href="#">上一页</a></li>'
else:
prev_page = '<li><a href="?page=%s">上一页</a></li>' % (self.current_page - 1,)
page_html_list.append(prev_page)
for i in range(pager_start, pager_end):
if i == self.current_page:
temp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i,)
else:
temp = '<li><a href="?page=%s">%s</a></li>' % (i, i,)
page_html_list.append(temp)
if self.current_page >= self.all_pager:
next_page = '<li class="disabled"><a href="#">下一页</a></li>'
else:
next_page = '<li><a href="?page=%s">下一页</a></li>' % (self.current_page + 1,)
page_html_list.append(next_page)
last_page = '<li><a href="?page=%s">尾页</a></li>' % (self.all_pager,)
page_html_list.append(last_page)
# 尾部添加标签
page_html_list.append('''
</nav>
</ul>
''')
return ''.join(page_html_list)
def index(request):
book_queryset = models.Book.objects.all()
# 两个参数, 当前页和数据数量
current_page = request.GET.get('page', 1)
all_count = book_queryset.count()
# 实例化出分页器对象
pagination_obj = Pagination(current_page=current_page, all_count=all_count)
# 切片获取当前页的数据
page_queryset = book_queryset[pagination_obj.start:pagination_obj.end]
return render(request, 'index.html', locals())
<table class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th>NO.</th>
<th>Book Title</th>
</tr>
</thead>
<tbody>
{% for book in page_queryset %}
<tr>
<td>{{ book.pk }}</td>
<td>{{ book.title }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="text-center">
{{ pagination_obj.page_html|safe }}
</div>
</div>