• 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=" 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">&laquo;</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">&raquo;</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。

    还是一句话:每学一点东西,就越发感觉还有好多东西可以学,啊啊啊。

  • 相关阅读:
    centos 7修改时间为中国时间
    颜色表及html代码
    前端日志监控体系
    测试开发必备技能:安全测试漏洞靶场实战
    Jmeter(三)----win10系统下如何修改Jmeter字体大小?
    Jmeter(二) ---Jmeter英文版本修改为中文
    Jmeter(一) ---Windows环境搭建
    跟着高手学复盘_初步理解
    小测试对 HTTP/2 的了解
    软件测试入坑建议
  • 原文地址:https://www.cnblogs.com/xiximayou/p/11789172.html
Copyright © 2020-2023  润新知