1. 程式人生 > >Python廖雪峰實戰web開發(Day12-編寫日誌列表頁)

Python廖雪峰實戰web開發(Day12-編寫日誌列表頁)

編寫一個日誌列表頁,想想我們期待它是怎樣的,有什麼樣的功能。
其實也無非諸如點進,刪除,修改日誌,把資料庫的日誌按照格式顯示在網頁面上,比方說一個網頁面設定顯示十篇日誌,當資料庫不足20篇日誌有超過10篇時,總頁數有兩頁。
那麼現在就著眼研究如何編寫實現日誌顯示格式吧。
首先,得注意的是要實現顯示規定數量的日誌,就是對資料庫裡面的blog表進行操作,在之前定義ORM框架的findall方法時,就定義了一個limit引數,也就是說只需將limit引數確定下來,就能確定返回對應範圍的日誌,之後就交給MVVC進行排版顯示了。
程式碼如下:

#用於選擇當前頁面
def get_page_index
(page_str):
p = 1 #初始化頁數取整 try: p = int(page_str) except ValueError as e: pass if p < 1: p = 1 return p #定義選取數量(每一頁都會選取相應選取數量的資料庫中日誌出來顯示) class Page(object): def __init__(self, item_count, page_index=1, page_size=10):#引數依次是:資料庫部落格總數,初始頁,一頁顯示部落格數 self.item_count = item_count self.page_size = page_size self.page_count = item_count // page_size + (1
if item_count % page_size > 0 else 0)#一共所需頁的總數 if (item_count == 0) or (page_index > self.page_count):#假如資料庫沒有部落格或全部部落格總頁數不足一頁 self.offset = 0 self.limit = 0 self.page_index = 1 else: self.page_index = page_index #初始頁 self.offset = self.page_size * (page_index - 1
) #當前頁數,應從資料庫的那個序列部落格開始顯示 self.limit = self.page_size #當前頁數,應從資料庫的那個序列部落格結束畫素 self.has_next = self.page_index < self.page_count #有否下一頁 self.has_previous = self.page_index > 1 #有否上一頁 def __str__(self): return 'item_count: %s, page_count: %s, page_index: %s, page_size: %s, offset: %s, limit: %s' % (self.item_count, self.page_count, self.page_index, self.page_size, self.offset, self.limit) __repr__ = __str__

然後編寫實現API:

#介面用於資料庫返回日誌,見manage_blogs.html
@get('/api/blogs')
async def api_blogs(*, page='1'):
    page_index = get_page_index(page)
    num = await Blog.findnumber('count(id)')#查詢日誌總數
    p = Page(num, page_index)
    if num == 0: #資料庫沒日誌
        return dict(page=p, blogs=())
    blogs = await Blog.findall(orderBy='create_at desc', limit=(p.offset, p.limit)) #選取對應的日誌
    return dict(page=p, blogs=blogs)#返回管理頁面資訊,及顯示日誌數

結合一下顯示日誌網頁原始碼:

{% extends '__base__.html' %}

{% block title %}日誌{% endblock %}

{% block beforehead %}

<script>
function initVM(data) {
    var vm = new Vue({
        el: '#vm',
        data: {
            blogs: data.blogs,
            page: data.page
        },
        methods: {
            edit_blog: function (blog) {
                location.assign('/manage/blogs/edit?id=' + blog.id);
            },
            delete_blog: function (blog) {
                if (confirm('確認要刪除“' + blog.name + '”?刪除後不可恢復!')) {
                    postJSON('/api/blogs/' + blog.id + '/delete', function (err, r) {
                        if (err) {
                            return alert(err.message || err.error || err);
                        }
                        refresh();
                    });
                }
            }
        }
    });
    $('#vm').show();
}
$(function() {
    getJSON('/api/blogs', {
        page: {{ page_index }}
    }, function (err, results) {
        if (err) {
            return fatal(err);
        }
        $('#loading').hide();
        initVM(results);
    });
});
</script>

{% endblock %}

{% block content %}

    <div class="uk-width-1-1 uk-margin-bottom">
        <div class="uk-panel uk-panel-box">
            <ul class="uk-breadcrumb">
                <li><a href="/manage/comments">評論</a></li>
                <li class="uk-active"><span>日誌</span></li>
                <li><a href="/manage/users">使用者</a></li>
            </ul>
        </div>
    </div>

    <div id="error" class="uk-width-1-1">
    </div>

    <div id="loading" class="uk-width-1-1 uk-text-center">
        <span><i class="uk-icon-spinner uk-icon-medium uk-icon-spin"></i> 正在載入...</span>
    </div>

    <div id="vm" class="uk-width-1-1">
        <a href="/manage/blogs/create" class="uk-button uk-button-primary"><i class="uk-icon-plus"></i> 新日誌</a>

        <table class="uk-table uk-table-hover">
            <thead>
                <tr>
                    <th class="uk-width-5-10">標題 / 摘要</th>
                    <th class="uk-width-2-10">作者</th>
                    <th class="uk-width-2-10">建立時間</th>
                    <th class="uk-width-1-10">操作</th>
                </tr>
            </thead>
            <tbody>
                <tr v-repeat="blog: blogs" >
                    <td>
                        <a target="_blank" v-attr="href: '/blog/'+blog.id" v-text="blog.name"></a>
                    </td>
                    <td>
                        <a target="_blank" v-attr="href: '/user/'+blog.user_id" v-text="blog.user_name"></a>
                    </td>
                    <td>
                        <span v-text="blog.create_at.toDateTime()"></span>
                    </td>
                    <td>
                        <a href="#0" v-on="click: edit_blog(blog)"><i class="uk-icon-edit"></i>
                        <a href="#0" v-on="click: delete_blog(blog)"><i class="uk-icon-trash-o"></i>
                    </td>
                </tr>
            </tbody>
        </table>

        <div v-component="pagination" v-with="page"></div>
    </div>

{% endblock %}