django实战(二)--带多字段模糊查询的分页(也是不容易)
上节我们实现了分页功能,这节我们要实现对模糊查询后的结果进行分页。(引入了bootstrap框架)
urls.py
from django.urls import path
from . import views
app_name='person'
urlpatterns=[
path('curd/',views.curd_index),
path('curd/<int:pn>',views.curd_index,name="curdindex"),
]
models.py
class Publisher(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=64,null=False,unique=True)
def __str__(self):
# return "publisher_name:{}".format(self.name)
return "{}".format(self.name)
class Book(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=128,null=False)
introduce=models.TextField(max_length=120)
publisher = models.ForeignKey(to='Publisher',on_delete=None)
def __str__(self):
return "book_title:{}".format(self.title)
class Meta:
ordering=['id']
你说我对单个表不就好了,为啥还要搞个外键出来!!!
views.py
from django.db.models import Q
from django.shortcuts import render
from .models import Book
from django.core.paginator import Paginator, EmptyPage
def curd_index(request,pn=1):
#获取前端收到的查询的值,默认值为空
query=request.GET.get('query')
#如果存在,则对title和publisher进行模糊查询
if query:
book_obj = Book.objects.all().filter(Q(title__contains=query)|Q(publisher__name__contains=query))
#否则取得所有的记录,并设置query的初始值为''
else:
query=''
book_obj=Book.objects.all()
#将取得的记录传给Paginator,每页显示5条
paginator=Paginator(book_obj,5)
#这里做异常判断,稍后再讲
try:
page=paginator.page(pn)
except EmptyPage:
page=paginator.page(1)
#将page和查询字段传给前端
context={
'page':page,
'query':query,
}
return render(request,'curd/curd.html',context=context)
curd.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css">
<script src="/static/bootstrap/js/bootstrap.js"></script>
<title>Document</title>
</head>
<body>
<div style="width: 100%";>
<h3 align="center">书籍列表</h3>
<table class="table" style="table-layout: fixed;">
<div style="float: right">
<form method="get" action="" >
<input type="text" name="query"/>
<input type="submit" name="submit" class="btn btn-primary input-sm"/>
</form>
</div>
<tr>
<th>id</th>
<th>title</th>
<th>publisher</th>
<th>introduce</th>
</tr>
<tr>
{% for item in page%}
<td>{{item.id}}</td>
<td>{{item.title}}</td>
<td>{{item.publisher}}</td>
<td>{{item.introduce}}</td>
</tr>
{% endfor %}
</table>
</div>
<!--底部分页按钮显示-->
<div style="position: absolute;top: 30 %;left: 44%">
<nav aria-label="Page navigation">
<div class="pagination">
<ul class="pagination" >
{% if page.has_previous %}
<li><a href="/curd/{{page.previous_page_number}}?query={{query}}" aria-label="Previous">
<span aria-hidden="true">«</span></a></li>
{% endif %}
{% for num in page.paginator.page_range%}
{%if pindex == page.number%}
<li><a href="">{{ num }}</a></li>
{%else%}
<li><a href="/curd/{{num}}?query={{query}}">{{ num }}</a></li>
{%endif%}
{% endfor %}
{% if page.has_next %}
<li><a href="{% url 'person:curdindex' page.next_page_number%}?query={{query}}" aria-label="Next">
<span aria-hidden="true">»</span></a></li>
{% endif %}
</ul>
</div>
</nav>
</div>
</body>
</html>
启动服务器后:
我们点击下一页:
注意到浏览器中地址变成了http://127.0.0.1:8000/curd/2?query=,接下来,我们尝试输入“p”
我们按title进行了模糊查询,但是浏览器地址为:http://127.0.0.1:8000/curd/3?query=p&submit=%E6%8F%90%E4%BA%A4。我们查询后的/curd/3这里不应该是1么,从第一页开始?这就是我们之前进行异常控制的原因。如果我们不设置,就会报错Emptypage,因为不是从第三页开始的。我们尝试下一页,浏览器地址:http://127.0.0.1:8000/curd/2?query=p,这正如我们所说,跳转到第二页了,同时,我们仍然位于模糊查询的列表中。因为我们在第一次进行模糊查询时,后端将从前端获得的query重新传回给了前端,并保存在url路径中,所以我们选择页面的时候,只是会改变页面的值,而后面的query仍然是存在的。
我们再输入"广州":
同样得到了按publisher选择的结果,这是因为我们在模糊查询中进行了选择。
补充:每记录一篇,都要参考不少别人的东西,由于django的多样性,别人写的不可能完全适合自己,这就需要自己从中提取对自己有益的东西。
技术总结:写完分页后,想到应该如何根据模糊查询后的结果进行分页呢?其实就是一个传参,接受参数的过程。其中遇到的另一个坑就是,自己非要利用外键进行关联查询,在进行模糊查询时,publisher是外键,不能直接用publisher__contains,而应该用publisher__name__contains,否则会报错:FieldError。
还是一句话:每学一点东西,就越发感觉还有好多东西可以学,啊啊啊。
- 知其所以然之永不遗忘的算法
- ZOOKEEPER集群搭建及测试
- 【Python环境】Scikit-Learn:开源的机器学习Python模块
- 【Python环境】可爱的 Python: 自然语言工具包入门
- 电脑静音工作,又听不到12306的来票音乐,纠结啊 !但春节前工作多任务重,不能安心工作,就动手做个“无声购票弹窗”工具吧!
- .net访问PostgreSQL数据库发生“找不到函数名”的问题追踪
- “领域驱动开发”实例之旅(1)--不一样的开发模式 一、分析业务需求。 二、设计领域对象模型 三、测试领域对象模型 四、设计业务处理类 五、设计Entity和Vi
- Java基础——左移和右移
- 【Python环境】利用 Python、SciKit 和文本分类来实现行为分析
- LJMM平台( Linux +Jexus+MySQL+mono) 上使用MySQL的简单总结
- 判断两个单链表是否相交(有环、无环两种)
- 【数据科学家】SparkR:数据科学家的新利器
- KMP算法浅析
- Bug修复问题
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 【Java】17 字符流
- 极坐标系在数据可视化中的巧妙运用
- 【Java】18 增强流
- 【Java】19 网络编程
- 【Java】20 基于 TCP 协议的网络编程
- 【Java】01 初识 Java
- 多张热图的排版技巧
- 【Java】02 数据类型与运算符
- StringBuilder/StringBuffer源码阅读笔记
- PAT (Advanced Level) Practice 1027 Colors in Mars (20 分)
- 【Java】21 基于 UDP 的网络编程
- PowerBI DAX 在矩阵分组区域内通用积累求和
- 【Java】22 网络连接
- 2015年ccf计算机职业认证资格考试第一题数列分段
- 数据结构题集(严书)查找 常见习题代码