BOOKMS是一個公司內部的圖書管理系統。 javascript
本系列用屢次迭代方法,逐步實現一個圖書管理系統BOOKMS。 css
本文主要介紹使用bootstrap美化前臺頁面和修改admin模塊的添加圖書模塊時使用豆瓣api獲取數據。 html
再前一節裏咱們一件能夠管理model(增刪改查)。可是界面是在是太簡陋,簡陋到但凡是個正常人估計都沒法接受。項目組裏沒有專業的前端的話,頁面美化是一個痛苦的事,可是有了bootstrap的幫助以後,咱們的頁面也能像模像樣。 前端
Bootstrap是Twitter推出的一個開源的用於前端開發的工具包。它由Twitter的設計師Mark Otto和Jacob Thornton合做開發,是一個CSS/HTML框架。Bootstrap提供了優雅的HTML和CSS規範,它便是由動態CSS語言Less寫成,與CSS框架Blueprint存在不少類似之處。Bootstrap一經推出後頗受歡迎,一直是GitHub上的熱門開源項目,包括NASA的code.nasa.gov和MSNBC(微軟全國廣播公司)的Breaking News都使用了該項目。 html5
能夠直接到http://twitter.github.com/bootstrap/下載使用。Bootstrap的出現造就了一大批黑硬工具條+小清新內容欄目組合的風格頁面。 java
咱們在項目裏增長以下目錄: jquery
很顯然,其中的css放置樣式表、html放置設計好的靜態頁面、js放置腳本。咱們把下載到的Bootstrap裏的文件分別放入。 git
要讓靜態資源起做用,咱們須要修改setting.py文件(還記得這文件吧,反覆改啊反覆改):github
import os STATICFILES_DIRS = ( os.path.dirname(__file__)+STATIC_URL, )
而後再在bookms的urls.py裏增長一條靜態文件的路由:django
from django.contrib.staticfiles.urls import staticfiles_urlpatterns urlpatterns += staticfiles_urlpatterns()
動server,就能夠經過http://127.0.0.1:8000/static/xxx 直接瀏覽靜態文件了。
首先來改造base.html。base就是全站的基礎母版(至關於asp.net的母版頁)。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>{% block title %} {% endblock %}</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="description" content=""> <meta name="author" content=""> <!-- Le styles --> <link href="/static/css/bootstrap.css" rel="stylesheet"> <style type="text/css"> body { padding-top: 60px; padding-bottom: 40px; } .sidebar-nav { padding: 9px 0; } </style> <link href="../assets/css/bootstrap-responsive.css" rel="stylesheet"> <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements --> <!--[if lt IE 9]> <script src="</SCRIPT'">http://html5shim.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> </head> <body> <div class="navbar navbar-fixed-top"> <div class="navbar-inner"> <div class="container-fluid"> <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </a> <a class="brand" href="#">圖書管理</a> <div class="btn-group pull-right"> <a class="btn dropdown-toggle" data-toggle="dropdown" href="#"> <i class="icon-user"></i> Username <span class="caret"></span> </a> <ul class="dropdown-menu"> <li><a href="#">我的資料</a></li> <li class="divider"></li> <li><a href="#">退出系統</a></li> </ul> </div> <div class="nav-collapse"> <ul class="nav"> <li class="active"><a href="#">首頁</a></li> <li><a href="#about">圖書管理</a></li> <li><a href="#about">關於</a></li> </ul> </div><!--/.nav-collapse --> </div> </div> </div> <div class="container-fluid"> <div class="row-fluid"> <div class="span2"> <div class="well sidebar-nav"> <ul class="nav nav-list"> <li class="nav-header">圖書管理</li> <li class="active"><a href="#">圖書列表</a></li> <li><a href="#">個人圖書</a></li> <li><a href="#">請求處理</a></li> </ul> </div><!--/.well --> </div><!--/span--> <div class="span10"> {% block content %} {% endblock %} </div><!--/span--> </div><!--/row--> <hr> <footer> <p>© Company 2012</p> </footer> </div><!--/.fluid-container--> <!-- Le javascript ================================================== --> <!-- Placed at the end of the document so the pages load faster --> <script src="/static/js/jquery.js"></script> <script src="/static/js/bootstrap-transition.js"></script> <script src="/static/js/bootstrap-alert.js"></script> <script src="/static/js/bootstrap-modal.js"></script> <script src="/static/js/bootstrap-dropdown.js"></script> <script src="/static/js/bootstrap-scrollspy.js"></script> <script src="/static/js/bootstrap-tab.js"></script> <script src="/static/js/bootstrap-tooltip.js"></script> <script src="/static/js/bootstrap-popover.js"></script> <script src="/static/js/bootstrap-button.js"></script> <script src="/static/js/bootstrap-collapse.js"></script> <script src="/static/js/bootstrap-carousel.js"></script> <script src="/static/js/bootstrap-typeahead.js"></script> </body> </html>
而後是咱們的list_book.html:
{% extends "base.html" %} {% block title %} 圖書列表 {% endblock %} {% block content %} <div class="row-fluid"> <a class="btn btn-success" href="{% url bookapp.views.create_book %}"> <span class=" icon-plus icon-white" ></span>增長圖書 </a> </div> {% for item in list_items.object_list %} <div class="row-fluid"> <div class="span1"> <img src="{{item.cover_img}}"/> </div> <div class="span11"> <h2>{{item.title}}</h2> <p>{{item.summary}}</p> <p> <a class="btn btn-info" href="{% url bookapp.views.view_book item.id %}"><span class=" icon-check icon-white" ></span>詳細 </a> <a class="btn btn-danger" href="{% url bookapp.views.edit_book item.id %}"> <span class=" icon-check icon-white" ></span>修改 </a> <a class="btn btn-danger" href="#"> <span class=" icon-check icon-white" ></span>歸還 </a> </p> </div> </div> <hr> {% endfor %} <div class="row-fluid"> {% if list_items.has_previous %} <a href="?page={{ list_items.previous_page_number }}">上一頁</a> {% endif %} <span class="current"> Page {{ list_items.number }} of {{ list_items.paginator.num_pages }}. </span> {% if list_items.has_next %} <a href="?page={{ list_items.next_page_number }}">下一頁</a> {% endif %} </div> {% endblock %}
這時候咱們能夠運行後去看看效果了
http://127.0.0.1:8000/bookapp/book/list
如今咱們的管理員已經能夠在後臺錄入圖書信息了,可是字段至關的多,錄入的工做量至關巨大。這裏咱們再偷懶一下,經過isbn到豆瓣api獲取數據,嘗試一下。
文藝青年都上豆瓣,可是更文藝的青年呢,直接用豆瓣api 。
豆瓣的API須要申請一個KEY,豆瓣也容許在不申請API Key的狀況下進行API調用。不過在這種狀況下,API調用被限制爲每分鐘請求不超過10次。使用API Key時,對訪問的限制較爲寬鬆,爲每分鐘40次,超過限制的話會被封禁。咱們測試的就先不用apikey了。
先看下豆瓣的api客戶端:
http://www.douban.com/service/apidoc/clients
咱們看其中的js客戶端。
<script type="text/javascript" src="http://www.douban.com/js/api.js?v=2" /><script type="text/javascript" src="http://www.douban.com/js/api-parser.js?v=1"></script>
這2個咱們都須要用到,這裏我直接下載了它們放到前面引入的靜態文件夾目錄 /bookms/static/js裏。
關於admin模塊的改造,推薦一篇文章:
http://www.ibm.com/developerworks/cn/opensource/os-django-admin/?ca=drs-tp4608
這裏咱們只須要改造添加圖書這個功能的模板頁面便可(輸入isbn後經過js調用豆瓣api,解析返回值填入各輸入框),因此咱們作的改造其實是擴展了添加圖書這個模板而已。在/bookms/templates/bookapp/book下新建一個html文件change_form.html
文件內容以下:
{% extends "admin/change_form.html" %} {% block extrahead %} <script src="/static/js/jquery.js"></script> <script src="/static/js/douban/api.js"></script> <script src="/static/js/douban/api-parser.js"></script> <script language="javascript"> $(document).ready(function(){ $("#id_isbn").after("<span>輸入10位或13位ISBN後回車,系統將自動獲取圖書信息</span>"); $(":input").keypress(function(e) { var key = e.which; if (13 == key) { e.preventDefault(); if(this.id=="id_isbn"){ fnFromDouban(); } var index = $(":input").index(this); var newIndex = index + 1; $(":input:eq(" + newIndex + ")").focus(); } }); }); function fnFromDouban(){ var reg=/^\d{10}|d{13}$/; if(!reg.test($("#id_isbn").val())){ return false; } var bookid; DOUBAN.apikey = '你的豆瓣api key'; DOUBAN.searchBooks({ keyword:$("#id_isbn").get(0).value, callback:function(bookinfo){ var list = DOUBAN.parseSubjects(bookinfo).entries; if(list==null||list.length==0){ alert("沒有這本書,檢查看看isbn是否出錯了呢。"); $("#id_isbn").focus(); }else{ bookid=list[0].nid; DOUBAN.getBook({ id:bookid, callback:function(re){ var book = DOUBAN.parseSubject(re); $("#id_title").val(book.title ? book.title : ""); $("#id_summary").val(book.summary ? book.summary : "--"); $("#id_subtitle").val(book.attribute["subtitle"]? book.attribute["subtitle"] : "--" ); $("#id_author").val(book.attribute["author"]); $("#id_translator").val(book.attribute["translator"]); $("#id_pages").val(book.attribute["pages"]); $("#id_price").val(book.attribute["price"]); $("#id_publisher").val(book.attribute["publisher"]); $("#id_pubdate").val(book.attribute["pubdate"]); $("#id_cover_img").val(book.link.image); $("#id_author_intro").val(book.attribute["author-intro"]); } }) } } }) return false; } </script> {% endblock %}
這裏咱們只不過擴展了一下模板。加入了一下js。js裏首先捕獲了input裏的回車按鍵,由於我這更偷懶的用了掃碼槍,掃碼槍默認的是掃到結果後幫你按個回車。
在回頭改造一下/bookms/bookapp/admin.py裏的BookAdmin類,讓admin模塊裏book類的顯示更符合咱們要求。
class BookAdmin(admin.ModelAdmin): list_display = (id','isbn', 'title', 'author','translator','publisher','type',) list_filter = ('type','publisher',) search_fields = (id','title','isbn',) list_per_page=20
來看看效果吧:
截圖會有些出入,由於我是從運行的系統裏截的~~~