1. 程式人生 > >實戰--帶多欄位模糊查詢的分頁(也是不容易)

實戰--帶多欄位模糊查詢的分頁(也是不容易)

上節我們實現了分頁功能,這節我們要實現對模糊查詢後的結果進行分頁。(引入了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">&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。

還是一句話:每學一點東西,就越發感覺還有好多東西可以學,啊啊