Python爬虫实战笔记_4-2 Django Paginator

练习Django Paginator的使用使页面更整洁。
第一阶段

首先要做的是搭建整个框架,包括如何连接数据库,如何应用model 以及Django Template Language的使用。

  1. 命题作文第一步当然要研究清楚命题。浏览器中打开代码检查器查看页面结构,提取出需要准备的信息,到models.py中定义自己的模式:
class ArticleList(Document):
    subject = StringField() # article subject
    author = StringField() # the author
    portrait = StringField() # a pic url of the author
    images = ListField(StringField()) # urls of images used in the article
    categories = ListField(StringField()) # tags of the article
    description = StringField() # the description of the article
    
    meta = {
        'collection': 'artiinfo' 
    }
  1. 准备数据。按照第一步中取出的数据模式新建数据表'artiinfo'。
    例子中第三篇文章的描述信息是两张图片,处理与其它文章不同,先把它放一边,只处理纯文字的文章。
authorlist = ['Tilo Mitra', 'Eric Ferra', 'Reid Burke', 'Andrew Wooldridge']
portraitlist = ['img/common/tilo-avatar.png', 'img/common/ericf-avatar.png', 'img/common/reid-avatar.png', 'img/common/andrew-avatar.png']
imageslist = [[], [],['http://farm8.staticflickr.com/7382/8907351301_bd7460cffb.jpg', 'http://farm8.staticflickr.com/7448/8915936174_8d54ec76c6.jpg'], []]
categorylist = [['CSS', 'Pure'], ['JavaScript'], [], ['YUI']]
description = ['Yesterday at CSSConf, we launched Pure – a new CSS library. Phew! Here are the slides from the presentation. Although it looks pretty minimalist, we’ve been working on Pure for several months. After many iterations, we have released Pure as a set of small, responsive, CSS modules that you can use in every web project.','Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.','','We are happy to announce the release of YUI 3.10.2! You can find it now on the Yahoo! CDN, download it directly, or pull it in via npm. We’ve also updated the YUI Library website with the latest documentation.']
titlelist = ['Introducing Pure', 'Everything You Need to Know About Grunt', 'Photos from CSSConf and JSConf', 'YUI 3.10.2 Released']

将上面准备好的数据插入数据表'blog.artiinfo'

  1. 准备静态资源,css, img等
    将网页中用到的图片资源,css文件放到static目录下,并在settings.py中指定引用路径。
  2. 定义model, 连接mongodb
    settings.py中添加连接mongodb的代码
from mongoengine import connect
connect('blog', host='127.0.0.1', port=27017)

Tip: model中的变量要与引用的数据表中的数据一一对应,名字也要完全相同,且一个不能多也一个不能少。切记!切记!

class ArticleList(Document):
    subject = StringField()
    author = StringField()
    portrait = StringField()
    images = ListField(StringField())
    categories = ListField(StringField())
    description = StringField()

    meta = {
        'collection': 'artiinfo'
    }
  1. 在views.py中应用定义的model
# Create your views here.
def menublog(request):
    info = ArticleList.objects
    context = {'artiinfo': info}
    return render(request, 'index.html', context)
  1. 编辑templates
{% load static %}
......
                {% for item in artiinfo %}
                <section class="post">
                    <header class="post-header">
                        <img class="post-avatar" alt="Eric Ferraiuolo's avatar" height="48" width="48" src="">

                        <h2 class="post-title">{{ item.subject }}</h2>

                        <p class="post-meta">
                            By <a class="post-author" href="#">{{ item.author }}</a> under
                            {% for ia in item.categories %}
                            <a class="post-category post-category-js" href="#">{{ ia }}</a>
                            {% endfor %}
                        </p>
                    </header>
                    <div class="post-description">
                        <p>
                            {{ item.description }}
                        </p>
                    </div>
                </section>
                {% endfor %}
......

第一阶段完成。
目前为止处理了文字相关的部分。作者的头像尚未加载。
除此之外,还有三个需要优化的问题:

  1. 标签的颜色与标签内容相关。
    示例页面中标签'CSS'的背景色为绿色,查看网页源码发现其class="post-category post-category-design";标签'Pure'的背景色为蓝色,class="post-category post-category-pure"。'post-category-design'与'post-category-pure'这两个class在CSS中被定义为不同的背景色。
    数据表中保存的标签信息并没其对应的class信息,只有文字:
    categorylist = [['CSS', 'Pure'], ['JavaScript'], [], ['YUI']]
    那么如何做匹配呢? 如何为各个标签指定对应的class。

  2. 四篇文章中有一篇的description是两张图片,其它都是文字描述。需要在templates中添加代码做相应的判断,是图片则显示图片,只有文字则显示文字。

  3. 示例页面中,文章分为置顶的与最近发布的两类,为了简化在第一阶段的学习中,把所有文章都加在最近发布的类别下面。 后面会为各文章添加一个字段用于标识其类别,并实现在templates中识别此标识为文章分类显示。

第二阶段

准备更多数据,实现分页显示。

  1. views.py中添加paginator相关的代码
from django.shortcuts import render
from myblog.models import ArticleList
from django.core.paginator import Paginator
# Create your views here.
def artilist(request):
      limit = 4
      arti_info = ArticleList.objects[:4]
      paginator = Paginator(arti_info, limit)
      page = request.GET.get('page',1)
      loaded = paginator.page(page)
      context = {
        'artiinfo': loaded
      }
      return render(request, 'index.html', context)
  1. templates模板中添加翻页按钮
            <div class="paginator">
            {% if artiinfo.has_previous %}
                <a href="?page={{ artiinfo.previous_page_number }}">Previous</a>
            {% endif %}
            <span>{{ artiinfo.number }} of {{ artiinfo.paginator.num_pages }}</span>
            {% if artiinfo.has_next %}
                <a href="?page={{ artiinfo.next_page_number }}">Next</a>
            {% endif %}
            </div>

分页显示效果图


Screen Shot 2016-07-16 at 6.26.59 PM.png
进阶学习

变量item.portrait中保存的是各文章作者的头像路径,且都是相对路径,相对于static。如'img/common/tilo-avatar.jpg'。
当路径是一个变量,且关联static目录时,引用方法如下
(https://docs.djangoproject.com/en/1.9/ref/templates/builtins/):

src="{% static item.portrait %}
  1. 优化问题一
    templates模板中加入了条件判断语句,实现标签与class的对应,从而各个标签显示各自特定的背景色。
 
                        <p class="post-meta">
                            By <a class="post-author" href="#">{{ item.author }}</a> under
                            {% for tag in item.categories %}
                                {% if tag == 'JavaScript' %}
                                    <a class="post-category post-category-js" href="#">{{ tag }}</a>
                                {% elif tag == 'CSS' %}
                                    <a class="post-category post-category-design" href="#">{{ tag }}</a>
                                {% elif tag == 'Pure' %}
                                    <a class="post-category post-category-pure" href="#">{{ tag }}</a>
                                {% elif tag == 'YUI' %}
                                    <a class="post-category post-category-yui" href="#">{{ tag }}</a>                             
                                {% else %}
                                    <a class="post-category" href="#">{{ tag }}</a>
                                {% endif %}
                            {% endfor %}
                        </p>
  1. 优化问题二
    对<div class="post-description">的修改如下:
...
                   <div class="post-description">
                        {% if item.images %}
                        <div class="post-images pure-g">
                            {% for img in item.images %}
                            <div class="pure-u-1 pure-u-md-1-2">
                                <a href="">
                                    ![]({{ img }})
                                </a>
                                <div class="post-image-meta">
                                    <h3></h3>
                                </div>
                            </div>
                            {% endfor %}
                        </div>
                        {% endif %}
                        <p>
                            {{ item.description }}
                        </p>
                    </div>
...

效果图


Screen Shot 2016-07-16 at 5.23.06 PM.png
  1. 优化问题三
    为每篇文章添加一个属性用来标识其是否为置顶。
    在templates中添加代码判断一篇文章是否是'pinned', 如果是则在'Pinned Post' wrapper中为其生成一个section。
    在'Recent Posts'中做类似的判断,当一篇文章不是'pinned', 则为其创建section。
            <!-- A wrapper for all the blog posts -->
            <div class="posts">
                <h1 class="content-subhead">Pinned Post</h1>
                <!-- A single blog post -->
                {% for item in artiinfo %}
                {% if item.level == 'pinned' %}
                <section class="post">
                     ......
                </section>
                {% endif %}
                {% endfor %}
            </div>
            <div class="posts">
                <h1 class="content-subhead">Recent Posts</h1>
                {% for item in artiinfo %}
                {% if item.level != 'pinned' %}
                <section class="post">
                     ......
                </section>
                {% endif %}
                {% endfor %}
            </div>

思考: 这样处理带来一个问题。作为读者希望标注了'pinned'的文章始终置顶。但用上面的方法,如果'pinned'文章在数据库中id为5, 也就是第五篇文章,paginator以4篇文章为一页,这篇'pinned'文章就被划分在第二页。最终显示的效果将是浏览第一页时,'pinned post'类别下没有文章,浏览第二页时,'pinned post'下显示出了这篇'pinned'文章。
这个效果显示不够好。
理想的处理方式考虑下来是将'pinned'单独筛选出来。仅对那些没有'pinned'标注的文章应用paginator分页显示。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,165评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,503评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,295评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,589评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,439评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,342评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,749评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,397评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,700评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,740评论 2 313
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,523评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,364评论 3 314
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,755评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,024评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,297评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,721评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,918评论 2 336

推荐阅读更多精彩内容