[Python+Django]初心者筆記7(建立list清單網頁,建立資料明細頁,list清單網頁分頁顯示paging)

[Python+Django]初心者筆記7(建立list清單網頁,建立資料明細頁,list清單網頁分頁顯示paging)

接下來要建立Book的list清單網頁,請在/catalog/urls.py裡面修改urlpatterns變數加入:
path('books/', views.BookListView.as_view(), name='books'),
所以整個urlpatterns變數將會變成像是下面這樣

urlpatterns = [
    #views.index:使用vews.py裡面定義的function:index()
    #name='index':.html的樣本template檔裡面,要寫href超連結語法的話,就會用到
    path('', views.index, name='index'),
    #加入Books資料表的list清單網頁的url mapping
    path('books/', views.BookListView.as_view(), name='books'),
    #加入Books資料表的詳細資料網頁的url mapping
    path('book/<int:pk>', views.BookDetailView.as_view(), name='book-detail'),
]

接著在/catalog/views.py下面加入:

#建立Book資料的List清單網頁
from django.views import generic

class BookListView(generic.ListView):
    model = Book
    #透過定義get_queryset()就可以自己定義想要的資料
    #沒有要自定義的話就註解掉get_queryset()
    def get_queryset(self):
        return Book.objects.filter(title__icontains='bike')[:5] #取前五筆資料,title包含關鍵字'bike'的
    #等等要去哪個路徑找.html檔案
    #不定義這個template_name的話,Django就會去預設的路徑尋找.html
    #預設的路徑是:/locallibrary/catalog/templates/catalog/book_list.html
    #不過目前暫時程式碼設定路徑的方式跟預設一樣就好    
    template_name = '/locallibrary/catalog/templates/catalog/book_list.html'

    #get_context_data()是用來建立自訂的Server side variable的
    #跟.Net MVC也挺像的
    def get_context_data(self, **kwargs):
        # Call the base implementation first to get the context
        context = super(BookListView, self).get_context_data(**kwargs)
        # Create any data and add it to the context
        context['some_data'] = 'This is just some data'
        return context

    #這是分頁機制, 以下設定一頁的最多資料筆數 = 1
    paginate_by = 1  


接著請新增這個超級無敵奇怪路徑下的.html檔案(路徑的資料夾請自行新增):/locallibrary/catalog/templates/catalog/book_list.html
html檔的內容如下
 

{% extends "base_generic.html" %}

{% block content %}
    <h1>Book List</h1>

    <!-- 在views.py的class BookListView定義的get_queryset()
    會自動傳送一個預設的變數名稱book_list過來,當作list清單網頁的資料 -->
    {% if book_list %}
    <ul>

      {% for book in book_list %}
      <li>
        <a href="{{ book.get_absolute_url }}">{{ book.title }}</a> ({{book.author}})
      </li>
      {% endfor %}

    </ul>
    {% else %}
      <p>There are no books in the library.</p>
    {% endif %}       
{% endblock %}


然後再來建立Book的明細網頁,請在catalog/views.py加入:

#從db取得某本Book的明細資料
#不需要寫什麼特殊的Query語法,Django將會自動做好binding
class BookDetailView(generic.DetailView):
    model = Book        


接著需建立Book的資料明細頁,請新增一個.html檔:/locallibrary/catalog/templates/catalog/book_detail.html
路徑資料夾請自行新增,而html檔的內容如下:

{% extends "base_generic.html" %}

{% block content %}
  <h1>Title: {{ book.title }}</h1>

  {% comment %} <p><strong>Author:</strong> <a href="{% url 'author-detail' book.author.pk %}">{{ book.author }}</a></p> <!-- author detail link not yet defined --> {% endcomment %}
  
  <p><strong>Author:</strong> <a href="">{{ book.author }}</a></p> <!-- author detail link not yet defined -->
  <p><strong>Summary:</strong> {{ book.summary }}</p>
  <p><strong>ISBN:</strong> {{ book.isbn }}</p> 
  <p><strong>Language:</strong> {{ book.language }}</p>  
  <p><strong>Genre:</strong> {% for genre in book.genre.all %} {{ genre }}{% if not forloop.last %}, {% endif %}{% endfor %}</p>  

  <div style="margin-left:20px;margin-top:20px">
    <h4>Copies</h4>
    {% comment %} book.bookinstance_set由來:當models.py只有定義單方向的bookinstance=>book的foreign key的關係
    的時候,Django提供了特殊的用法 OOXX_set,讓book=>bookinstance雖沒有被定義,也可以使用     {% endcomment %}
    {% for copy in book.bookinstance_set.all %}
    <hr>
    <p class="{% if copy.status == 'a' %}text-success{% elif copy.status == 'm' %}text-danger{% else %}text-warning{% endif %}">{{ copy.get_status_display }}</p>
    {% if copy.status != 'a' %}<p><strong>Due to be returned:</strong> {{copy.due_back}}</p>{% endif %}
    <p><strong>Imprint:</strong> {{copy.imprint}}</p>
    <p class="text-muted"><strong>Id:</strong> {{copy.id}}</p>
    {% endfor %}
  </div>
{% endblock %}

如此一來清單頁以及明細頁就完成了
清單頁:

明細頁:上面明細頁的Author的foreign​ key的超連結部分尚未實做,將於下個文章說明
這篇先這樣…



參考資料:
Django Tutorial Part 6: Generic list and detail views
https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Generic_views