1. 程式人生 > >004---設計新增和編輯書籍頁面

004---設計新增和編輯書籍頁面

 

 

現在就來新增書籍吧。為他設計一條url。

1 path('book_add/', views.book_add, name='book_add'), # 走bood_add檢視函式

 別忘了更改index.html新增書籍的這條a標籤。

<a href="{% url 'book_add' %}" class="btn btn-default" style="margin-top:10px;margin-bottom: 10px">新增書籍</a>

新增書籍,代表要提交資料,所以form表單是少不了的。

而且,新增書籍還要為他新增與其對應的出版社,作者。所以檢視就要獲取所有出版社,作者,渲染到book_add.html頁面。

檢視部分:

1 def book_add(request):
2     pub_lt = Publish.objects.all() # 資料庫獲取所有出版社
3     author_lt = Author.objects.all() # 資料庫獲取所有作者
4     return render(request, 'book_add.html', {"pub_list": pub_lt, "author_list": author_lt})

 

模版部分(book_add.html):

 1 {% extends 'base.html' %}
 2 
 3 {% block title %}
 4 <title>新增書籍</title>
 5 {% endblock %}
 6 
 7 {% block body %}
 8 <h3>新增書籍</h3>
 9     {% include 'form.html' %}
10 {% endblock %}

 

也許你會感到奇怪,為什麼新增頁面這麼少程式碼。沒錯、就是這麼少。因為用到了繼承base.html。我只要寫個form表單就行。可這也沒看到form表單,因為後面圖書還有個編輯頁面。其實也是form表單。所以

這裡有用到了抽取模版。把form表單抽取出來,使用的話是{% include 'form.html' %}。代表把form.html拿到這來。

模版部分(form.html):

 1 <form action="" method="post">
 2     {% csrf_token %}
 3     <div class="form-group">
 4         <label for="title">書籍名稱</label>
 5         <input type="text" name="title" class="form-control" id="title" value="{{ book.title }}">
 6     </div>
 7     <div class="form-group">
 8         <label for="price">價格</label>
 9         <input type="text" name="price" id="price" class="form-control" value="{{ book.price }}">
10     </div>
11     <div class="form-group">
12         <label for="pub_date">出版日期</label>
13         <input type="date" name="pub_date" class="form-control" id="pub_date" value="{{ book.pub_date|date:"Y-m-d" }}">
14     </div>
15     <div class="form-group">
16         <label for="">出版社</label>
17         <select name="pubs" id="" class="form-control">
18             {% for pub in pub_list %}
19                 {% if pub.id == book.publish.id %}
20                     <option value="{{ pub.id }}" selected>{{ pub.name }}</option>
21                 {% else %}
22                     <option value="{{ pub.id }}">{{ pub.name }}</option>
23                 {% endif %}
24  {% endfor %} 25 </select> 26 </div> 27 <div class="form-group"> 28 <label for="">作者</label> 29 <select name="authors" id="" class="form-control" multiple> 30  {% for author in author_list %}32  {% if author in book.author.all %} 33 <option value="{{ author.id }}" selected>{{ author.name }}</option> 34  {% else %} 35 <option value="{{ author.id }}">{{ author.name }}</option> 36  {% endif %} 38  {% endfor %} 39 </select> 40 </div> 41 <input type="submit" value="提交" class="btn btn-warning"> 42 </form>

注意:

  • Django提交form表單。要加 {% csrf_token %}。不然會報403錯誤
  • 還是先來看看這個繁瑣的form表單,每個input後面都有value。如果單單是新增書籍的話,vlaue可以為空。但是考慮到後面還有個編輯頁面。編輯的時候,input是有值的。所以我們也不能一步步往死裡寫,立馬轉彎,設計一條編輯書籍的url。
  • 1 re_path('^book_edit/(?P<book_id>\d+)/$', views.book_edit, name='book_edit'),  
    2 # 匹配的url是這種的 :/book_edit/1/   添加了一個有名分組,用來捕獲書籍id。走的是book_edit檢視

     到這裡最好把之前要用到這條url的地方改一下。index.html有個編輯按鈕:

    1                     <a href="{% url 'book_edit' book.id %}">
    2                         <button class="btn btn-success">編輯</button>
    3                     </a>
    4 <!--用到了反向解析,因為index頁面每一行表記錄,都有一本書,書的id就是你要編輯的那本書的id-->

     

  改完模板部分就是寫book_edit檢視了。 

1 def book_edit(request, book_id):
2     book = Book.objects.filter(pk=book_id).first()
3     pub_lt = Publish.objects.all()
4     authors = Author.objects.all()
5     return render(request, 'book_edit.html', {"book": book, "pub_list": pub_lt, "author_list": authors})
6 # 和新增書籍不同的是,我們是編輯書籍,那本書原來的資料要保留渲染出來,所以我們的url後面要捕獲id。這裡資料庫過濾編輯的這本書物件。
7 # 渲染到之前的form表單頁面的value中,以後編輯書籍,就會自動2填充書修改之前的資料
  • 還有一些你不懂的地方,我是把編輯和新增一同寫了,所以form表單中出版社和作者那裡還有for迴圈,還有if判斷。這麼多都是為編輯做鋪墊。
  • 本來單單新增書籍,直接for迴圈後端傳來的pub_list就行。但是編輯就不一樣,編輯不僅value要填充,顯示的時候我們也要用select保留書籍原來所屬的出版社,所以我們for迴圈出版社,得到每一個出版社物件後,再if判斷我們此時編輯的書籍的出版社物件和for迴圈的出版社物件是否一致,如果一樣,就再option標籤加select表示,如果不一樣,就正常顯示,並不影響新增頁面。
  • for迴圈作者也是一樣的道理。不同的是,一個書籍可能有多個作者,所以是判斷迴圈出來的作者物件在不在這本書籍的所有作者中,是,就select。因為多選所以select  還要加 multiple
  • 其實這是一個比較繁瑣的介面,Django還有高階一點的玩法,我這裡不說,程式碼量減少的不是一般的多。。。什麼邏輯都不自己寫。我給你看個圖對比下。

    就是這麼簡單粗暴。。。

 寫到這裡,來看看效果吧。

發現一個很大的問題,沒有出版社和作者,渲染不出來,所以我們手動去資料庫加幾條資料。

再來看新增書籍頁面:

 

 來試試編輯:

注意url。書籍原來的資訊就這樣顯現出來,歸功於那個form表單。