目录
sweetalert 插件
bulk_create 批量插入数据
分页器
简易版本的分页器的推导
自定义分页器的使用 (组件)
sweetalert 插件
有这么一个需求:
? 当用户进行一个删除数据的操作时, 弹出一个二次确认的动态框样式?
其实, 这里就可以使用 sweetalert 插件实现.
首先先下载该插件: Bootstrap-sweetalert 项目 https://github.com/lipis/bootstrap-sweetalert
上图下载完毕, 解压后找到 dist 文件夹, 拷贝到当前项目的 static 文件夹下, 导入此文件的两个文件, 和 Bootstrap 框架中的 CSS,JS 文件导入方式相同.
要引入的弹出框模板在这里: A beautiful "replacement" for JavaScript's alert https://lipis.github.io/bootstrap-sweetalert/
示例:
本示例选择的弹出框和模板如下:
- 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
- },
- function(isConfirm) {
- if (isConfirm) {
- swal("Deleted!", "Your imaginary file has been deleted.", "success");
- } else {
- swal("Cancelled", "Your imaginary file is safe :)", "error");
- }
- });
- # models.py
- from django.db import models
- # Create your models here.
- class User(models.Model):
- username = models.CharField(max_length=32)
- age = models.IntegerField()
- gender_choices = (
- (1,'male'),
- (2,'female'),
- (3,'others')
- )
- gender= models.IntegerField(choices=gender_choices)
- # urls.py
- from app01 import views
- urlpatterns = [
- url(r'^admin/', admin.site.urls),
- url(r'^home/', views.home,name='xxx'),
- ]
- # views.py
- from django.shortcuts import render
- # Create your views here.
- from app01 import models
- from django.http import JsonResponse
- def home(request):
- import time
- if request.is_ajax():
- back_dic={'code':1000,'msg':''}
- delete_id = request.POST.get('delete_id')
- time.sleep(3)
- models.User.objects.filter(pk=delete_id).delete()
- back_dic['msg']= '数据已经被删掉了!'
- return JsonResponse(back_dic)
- queryset_obj = models.User.objects.all()
- return render(request,'home.html',locals())
- <!--home.html-->
- <!DOCTYPE HTML>
- <HTML lang="en">
- <head>
- <meta charset="UTF-8">
- <title>
- Title
- </title>
- <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js">
- </script>
- {% load static %}
- <link rel="stylesheet" href="{% static'bootstrap-3.3.7/css/bootstrap.min.css'%}">
- <link rel="stylesheet" href="{% static'dist/sweetalert.css'%}">
- <script src="{% static'bootstrap-3.3.7/js/bootstrap.min.js'%}">
- </script>
- <script src="{% static'dist/sweetalert.js'%}">
- </script>
- <style>
- div.sweet-alert h2{ padding: 10px; }
- </style>
- </head>
- <body>
- <div class="container-fluid">
- <div class="row">
- <div class="col-md-8 col-md-offset-2">
- <h2 class="text-center">
- 数据显示
- </h2>
- <br>
- <table class="table table-striped table-bordered table-hover">
- <thead>
- <tr>
- <th>
- 序号
- </th>
- <th>
- 姓名
- </th>
- <th>
- 年龄
- </th>
- <th>
- 性别
- </th>
- <th class="text-center">
- 操作
- </th>
- </tr>
- </thead>
- <tbody>
- {% for userObj in queryset_obj %}
- <tr>
- <td>
- {{ forloop.counter }}
- </td>
- <td>
- {{ userObj.usernmae }}
- </td>
- <td>
- {{ userObj.age }}
- </td>
- <td>
- {{ userObj.get_gender_display }}
- </td>
- <td class="text-center">
- {#href 为空时, 代表重新刷新页面, 所以浏览器页面点击删除按钮弹出框转瞬即逝 #}
- <a href="" class="btn btn-primary btn-sm ">
- 编辑
- </a>
- {# 在 for 循环内部不能使用 id, 因为 id 要唯一不重复, 只能用 class 属性, 所以给 class 加了一个 cancel#}
- <a href="#" class="btn btn-danger btn-sm cancel" userId={{ userObj.pk
- }}>
- 删除
- </a>
- </td>
- </tr>
- {% endfor %}
- </tbody>
- </table>
- </div>
- </div>
- </div>
- <script>
- $('.cancel').click(function() {
- {#获取的是被点击的a标签对象#
- }
- var $btn = $(this); {#swal可以填三个参数,
- 最后一个是控制弹出框小图标颜色的提示信息,
- 有info和warning两种#
- }
- swal({
- title: "确定?",
- text: "删除将不能恢复改文件了!",
- type: "warning",
- showCancelButton: true,
- confirmButtonClass: "btn-danger",
- confirmButtonText: "删除!",
- cancelButtonText: "不, 取消!",
- closeOnConfirm: false,
- closeOnCancel: false,
- {#获取加速的动态#
- }
- showLoaderOnConfirm: true
- },
- function(isConfirm) {
- if (isConfirm) {
- // 朝后端发送 Ajax 请求
- $.Ajax({
- url: '',
- type: 'post',
- data: {
- 'delete_id': $btn.attr('userId')
- },
- success: function(data) {
- if (data.code == 1000) {
- swal("删除成功!", data.msg, "success");
- // 通过 DOM 操作 来直接操作标签, 删除标签 tr, 就是当前用户要删除的这条数据记录
- $btn.parent().parent().remove()
- }
- }
- });
- } else {
- swal("取消", "文件安全啦! :)", "错误");
- }
- });
- })
- </script>
- </body>
- </HTML>
bulk_create 批量插入数据
当要实现批量插入数据的时候, 就可以 bulk_create, 能大幅度缩短插入的时间;
- def index(request):
- # 普通插入方式:
- # for i in range(1000):
- # models.Book.objects.create(title='第 %s 本书'%i)
- # 使用 bulk_create 批量插入
- book_list = []
- for i in range(2000):
- book_list.append(models.Book(title='第 %s 本书'%i))
- models.Book.objects.bulk_create(book_list) # 这里直接放的是列表
- book_queryset=models.Book.objects.all()
- return render(request,'index.html',locals())
- <!--index.html-->
- <!DOCTYPE HTML>
- <HTML lang="en">
- <head>
- <meta charset="UTF-8">
- <title>
- Title
- </title>
- <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js">
- </script>
- <link rel="stylesheet" href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css">
- <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js">
- </script>
- </head>
- <body>
- {% for book_obj in book_queryset %}
- <p>
- {{ book_obj.title }}
- </p>
- {% endfor %}
- </body>
- </HTML>
分页器
简易版本的分页器的推导
- def index(request):
- # 获取用户想要查看的页码
- current_page = int(request.GET.get('page', 1))
- book_queryset = models.Book.objects.all() # 获取所有书籍对象
- book_num = book_queryset.count() # 统计所有书籍条数目
- book_page,more = divmod(book_num,10) # 统计书籍的分页
- per_page_num = 10 # 定义每页展示 10 条
- start_page = (current_page - 1) * per_page_num # 每页其实条数
- end_page = current_page * per_page_num # 每页终止的条数
- if more:
- book_page += 1
- HTML = ''
- xxx = current_page # 对用户的当前选页赋值一个变量
- if current_page <6:
- xxx = 6 # 当用户选择小于 6 的数字, 数字不会变成负数
- for i in range(xxx-5,xxx+6): # 共展示给用户的指定的 10 页
- if current_page==i:
- # 将 10 页内容的标签以字符串的形式进行拼接, 如果是当前页, 显示激活态
- HTML+='<li class="active"><a href="?page=%s">%s</a></li>'%(i,i)
- else:
- HTML+='<li><a href="?page=%s">%s</a></li>'%(i,i) # 不是当前页的正常显示
- book_queryset=book_queryset[start_page:end_page]
- return render(request,'index.html',locals())
- <!DOCTYPE HTML>
- <HTML lang="en">
- <head>
- <meta charset="UTF-8">
- <title>
- Title
- </title>
- <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js">
- </script>
- {% load static %}
- <link rel="stylesheet" href="{% static'bootstrap-3.3.7/css/bootstrap.min.css'%}">
- <link rel="stylesheet" href="{% static'dist/sweetalert.css'%}">
- <script src="{% static'bootstrap-3.3.7/js/bootstrap.min.js'%}">
- </script>
- <script src="{% static'dist/sweetalert.js'%}">
- </script>
- </head>
- <body>
- <div class="container-fluid">
- <div class="row">
- <div class="col-md-8 col-md-offset-2">
- {% for book_obj in book_queryset %}
- <p>
- {{ book_obj.title }}
- </p>
- {% endfor %}
- <nav aria-label="Page navigation">
- <ul class="pagination">
- <li>
- <a href="#" aria-label="Previous">
- <span aria-hidden="true">
- «
- </span>
- </a>
- </li>
- {{ HTML|safe }}
- <li>
- <a href="#" aria-label="Next">
- <span aria-hidden="true">
- »
- </span>
- </a>
- </li>
- </ul>
- </nav>
- </div>
- </div>
- </div>
- </body>
- </HTML>
自定义分页器的使用 (组件)
类封装的组件, 包括 Bootstrap 中分页的框架也都封装进去了.
- class Pagination(object):
- def __init__(self,current_page,all_count,per_page_num=2,pager_count=11):
- """
- 封装分页相关数据
- :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)
调用以上接口:
- # views.py
- def index(request):
- book_queryset = models.Book.objects.all()
- # 自定义分页器的使用
- current_page = request.GET.get('page', 1)
- all_count = book_queryset.count()
- page_obj=Pagination(current_page,all_count,per_page_num=10,pager_count=5)
- page_queryset = book_queryset[page_obj.start:page_obj.end]
- return render(request,'index.html',locals())
- // index.HTML
- <!DOCTYPE HTML>
- <HTML lang="en">
- <head>
- <meta charset="UTF-8">
- <title>
- Title
- </title>
- <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js">
- </script>
- {% load static %}
- <link rel="stylesheet" href="{% static'bootstrap-3.3.7/css/bootstrap.min.css'%}">
- <link rel="stylesheet" href="{% static'dist/sweetalert.css'%}">
- <script src="{% static'bootstrap-3.3.7/js/bootstrap.min.js'%}">
- </script>
- <script src="{% static'dist/sweetalert.js'%}">
- </script>
- </head>
- <body>
- <div class="container-fluid">
- <div class="row">
- <div class="col-md-8 col-md-offset-2">
- {% for book_obj in page_queryset %}
- <p>
- {{ book_obj.title }}
- </p>
- {% endfor %} {{ page_obj.page_html|safe }}
- </div>
- </div>
- </div>
- </body>
- </HTML>
来源: http://www.bubuko.com/infodetail-3314754.html