5.1 批量插入记录
# 方法一
for i in range(100):
Book.objects.create(title='西游记')
# 方法二(推荐)
book_list = []
for i in range(100):
obj = Book(title='西游记')
book_list.append(obj)
Book.objects.bulk_create(book_list)
5.2 批量显示记录
-
views.py
from django.core.paginator import Paginator, EmptyPage # 1、获取所有图书记录 book_list = Book.objects.all() # 2、分页处理,每页显示10条 paginator = Paginator(book_list, 10) # 3、当前页码 current_page_num = int(request.GET.get('page',1)) # 取不到,设置为1 try: # 正常页码 current_page = paginator.page(current_page_num) except EmptyPage as e: # 错误页码,设置为1 current_page = paginator.page(1) # 4、显示的页面总个数:(num * 2) + 1 num = 3 if paginator.num_pages > (num * 2) + 1: if current_page_num - num <= 0: page_range = range(1, (num * 2) + 2) elif current_page_num + num > paginator.count: page_range = range(paginator.count - (num * 2), paginator.count + 1) else: page_range = range(current_page_num - num, current_page_num + num + 1) else: page_range = paginator.page_range print(paginator.count) # 数据总数 print(paginator.num_pages) # 总页数 print(paginator.page_range) # 页码列表:range(1,num_pages+1)
-
index.html
<!-- 3、遍历当前页所有书籍 --> {% for book in current_page %} {% endfor %} <!-- 4、上一页 --> {% if current_page.has_previous %} <li> <a href="?page={{ current_page.previous_page_number }}" aria-label="Next"> <span aria-hidden="true">«</span> </a> </li> {% else %} <!-- 没有上一页:disabled、javascript:0 --> <li class="disabled"> <a href="javascript:0" aria-label="Next"> <span aria-hidden="true">«</span> </a> </li> {% endif %} <!-- 4、所有分页 --> {% for i in page_range %} <!-- 当前页:active --> {% if current_page_num == i %} <li class="active"><a href="?page={{ i }}">{{ i }}</a></li> {% else %} <li><a href="?page={{ i }}">{{ i }}</a></li> {% endif %} {% endfor %} <!-- 4、下一页 --> {% if current_page.has_next %} <li> <a href="?page={{ current_page.next_page_number }}" aria-label="Next"> <span aria-hidden="true">»</span> </a> </li> {% else %} <!-- 没有下一页:disabled、javascript:0 --> <li class="disabled"> <a href="javascript:0" aria-label="Next"> <span aria-hidden="true">»</span> </a> </li> {% endif %} <!-- 是否有上一页:current_page.has_previous --> <!-- 上一页:current_page.previous_page_number --> <!-- 是否有下一页:current_page.has_next --> <!-- 下一页:current_page.next_page_number -->
5.3 自定义分页器
-
分页器模块
pagination.py
""" 分页组件 """ class Pagination(object): def __init__(self, current_page, all_count, base_url, query_params, per_page=20, pager_page_count=11): """ 分页初始化 :param current_page: 当前页码 :param all_count: 数据库中总条数 :param base_url: 基础URL :param query_params: QueryDict对象,内部含所有当前URL的原条件 :param pager_page_count: 页面上最多显示的页码数量 """ self.base_url = base_url self.query_params = query_params self.per_page = per_page self.all_count = all_count self.pager_page_count = pager_page_count pager_count, b = divmod(all_count, per_page) if b != 0: pager_count += 1 self.pager_count = pager_count half_pager_page_count = int(pager_page_count / 2) self.half_pager_page_count = half_pager_page_count # 格式错误的页码或不在范围内的页面,设置为默认值1 try: self.current_page = int(current_page) if not (0 < self.current_page <= self.pager_count): raise Exception() except Exception as e: self.current_page = 1 @property def start(self): """ 数据获取值起始索引 :return: """ return (self.current_page - 1) * self.per_page @property def end(self): """ 数据获取值结束索引 :return: """ return self.current_page * self.per_page def page_html(self): """ 生成HTML页码 :return: """ # 如果数据总页码pager_count<11 pager_page_count if self.pager_count < self.pager_page_count: pager_start = 1 pager_end = self.pager_count else: # 数据页码已经超过11 # 判断: 如果当前页 <= 5 half_pager_page_count if self.current_page <= self.half_pager_page_count: pager_start = 1 pager_end = self.pager_page_count else: # 如果: 当前页+5 > 总页码 if (self.current_page + self.half_pager_page_count) > self.pager_count: pager_end = self.pager_count pager_start = self.pager_count - self.pager_page_count + 1 else: pager_start = self.current_page - self.half_pager_page_count pager_end = self.current_page + self.half_pager_page_count page_list = [] if self.current_page <= 1: prev = '<li><a href="javascript: 0;">上一页</a></li>' else: self.query_params['page'] = self.current_page - 1 prev = '<li><a href="%s?%s">上一页</a></li>' % (self.base_url, self.query_params.urlencode()) page_list.append(prev) for i in range(pager_start, pager_end + 1): self.query_params['page'] = i if self.current_page == i: tpl = '<li class="active"><a href="%s?%s">%s</a></li>' % ( self.base_url, self.query_params.urlencode(), i,) else: tpl = '<li><a href="%s?%s">%s</a></li>' % (self.base_url, self.query_params.urlencode(), i,) page_list.append(tpl) if self.current_page >= self.pager_count: nex = '<li><a href="javascript: 0;">下一页</a></li>' else: self.query_params['page'] = self.current_page + 1 nex = '<li><a href="%s?%s">下一页</a></li>' % (self.base_url, self.query_params.urlencode(),) page_list.append(nex) page_str = "".join(page_list) return page_str
-
视图函数调用
from pagination import Pagination per_page_count = 10 all_count = self.model_class.objects.all().count() query_params = request.GET.copy() query_params._mutable = True pager = Pagination( current_page=request.GET.get('page'), all_count=all_count, base_url=request.path_info, query_params=query_params, per_page=self.per_page_count, ) data_list = self.model_class.objects.all()[pager.start:pager.end]
-
html文件加载
<nav> <ul class="pagination"> {{ pager.page_html|safe }} </ul> </nav>
-
css样式
.nav { min-width: 980px; height: 48px; background-color: #2F72AB; color: #ffffff; line-height: 48px; overflow: visible; font-size: 12px; } .nav .logo-area { width: 220px; overflow: hidden; height: 48px; text-align: center; background-color: #1c5a9c; } .nav .logo-area > a { color: #ffffff; text-decoration: none; display: inline-block; } .nav .logo-area .logo { height: 37px; width: 37px; float: left; margin: 6px; margin-right: 10px; } .nav .left-menu { font-size: 13px; } .nav .left-menu .menu-item { display: inline-block; padding: 0 15px; cursor: pointer; position: relative; color: white; text-decoration: none; } .nav .left-menu .menu-item:hover { background-color: #337ab7; } .nav .left-menu .menu-item .more-info { display: none; position: absolute; top: 48px; left: 0; border: 1px solid rgba(0, 0, 0, .15); -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175); box-shadow: 0 6px 12px rgba(0, 0, 0, .175); background-color: #fff; color: #333; z-index: 1003; } .nav .left-menu .menu-item:hover .more-info { display: block; } .nav .left-menu .menu-item .more-info .more-item { display: block; min-width: 120px; padding: 0 15px; line-height: 35px; text-decoration: none; color: #000000; } .nav .left-menu .menu-item .more-info .more-item:hover { background-color: #f1f0f0; } .nav .right-menu .user-menu { padding: 0 8px; cursor: pointer; color: white; text-decoration: none; } .nav .right-menu .user-menu:hover { background-color: #337ab7; } .nav .right-menu .user-info { padding: 0 30px 0 10px; height: 48px; position: relative; } .nav .right-menu .user-info:hover .avatar { background-color: #337ab7; } .nav .right-menu .user-info .avatar { display: inline-block; padding: 0 10px; height: 48px; } .nav .right-menu .user-info .avatar img { /* margin-top: 2px;*/ } .nav .right-menu .user-info .more-info { display: none; position: absolute; top: 48px; right: 20px; border: 1px solid rgba(0, 0, 0, .15); -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175); box-shadow: 0 6px 12px rgba(0, 0, 0, .175); background-color: #fff; color: #333; z-index: 1002; } .nav .right-menu .user-info:hover .more-info { display: block; } .nav .right-menu .user-info .more-info .more-item { display: block; min-width: 160px; padding: 0 15px; line-height: 35px; text-decoration: none; color: #000000; } .nav .right-menu .user-info .more-info .more-item:hover { background-color: #f1f0f0; }