使用Django開發一個圖書管理系統 05---改造界面


BOOKMS是一個公司內部的圖書管理系統。

本系列用多次迭代方法,逐步實現一個圖書管理系統BOOKMS。

本文主要介紹使用bootstrap美化前台頁面和修改admin模塊的添加圖書模塊時使用豆瓣api獲取數據。

再前一節里我們一件可以管理model(增刪改查)。但是界面是在是太簡陋,簡陋到但凡是個正常人估計都無法接受。項目組里沒有專業的前端的話,頁面美化是一個痛苦的事,但是有了bootstrap的幫助之后,我們的頁面也能像模像樣。

一。Bootstrap介紹

Bootstrap是Twitter推出的一個開源的用於前端開發的工具包。它由Twitter的設計師Mark OttoJacob Thornton合作開發,是一個CSS/HTML框架。Bootstrap提供了優雅的HTML和CSS規范,它即是由動態CSS語言Less寫成,與CSS框架Blueprint存在很多相似之處。Bootstrap一經推出后頗受歡迎,一直是GitHub上的熱門開源項目,包括NASA的code.nasa.gov和MSNBC(微軟全國廣播公司)的Breaking News都使用了該項目。

可以直接到http://twitter.github.com/bootstrap/下載使用。Bootstrap的出現造就了一大批黑硬工具條+小清新內容欄目組合的風格頁面。

二。項目改造,引入靜態資源

我們在項目里增加如下目錄:

image

很顯然,其中的css放置樣式表、html放置設計好的靜態頁面、js放置腳本。我們把下載到的Bootstrap里的文件分別放入。

要讓靜態資源起作用,我們需要修改setting.py文件(還記得這文件吧,反復改啊反復改):

import os
STATICFILES_DIRS = (
os.path.dirname(__file__)+STATIC_URL,
)

然后再在bookms的urls.py里增加一條靜態文件的路由:

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>&copy; 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

image

四。改造后台admin模塊,調用豆瓣api

現在我們的管理員已經可以在后台錄入圖書信息了,但是字段相當的多,錄入的工作量相當巨大。這里我們再偷懶一下,通過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

來看看效果吧:

image

截圖會有些出入,因為我是從運行的系統里截的~~~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM