PyxYuYu/MyBlog

Django学习记录(十二):Django by example -- Blog(八)

PyxYuYu opened this issue · 0 comments

The land did not move, but moved. The sea was not still, yet was still.

0x01 Django

  • Build a Blog Application
    • Creating templates for your views

      • 编辑 post/list.html ,继承 blog/base.html
        {% extends "blog/base.html" %}
      
        {% block title %}My Blog{% endblock %}
      
        {% block content %}
            <h1>My Blog</h1>
            {% for post in posts %}
                <h2>
                    <a href="{{ post.get_absolute_url }}">
                        {{ post.title }}
                    </a>
                 </h2>
                 <p class="date">
                     Published {{ post.publish }} by {{ post.author }}
                 </p>
                 {{ post.body|truncatewords:30|linebreaks }}
            {% endfor %}
        {% endblock %}
      • {% extends %} : 继承的标签,继承 blog/base.hteml,之前的两处 blocktitlecontent 填入相应的内容
      • post.body : 显示内容的地方用了两个过滤标签,一个是截断 truncatewords:30,一个是换行符 linebreaks
      • 编辑 post/detail.html ,同样继承 blog/base.html
        {% extends "blog/base.html" %}
      
        {% block title %}{{ post.title }}{% endblock %}
      
        {% block content %}
            <h1>{{ post.title }}</h1>
            <p class="date">
                Published {{ post.publish }} by {{ post.author }}
            </p>
            {{ post.body|linebreaks }}
        {% endblock %}  
      • 注意:
        • 发布的文章必须属性是 published
        • views.pypublish__year 等的 双下划线 代表属性的意思
    • Adding pagination

      • Django 有一个内建的控制分页类来管理文章页数
      • 编辑 views.py
        from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
      
        def post_list(request):
            object_list = Post.published.all()
            paginator = Paginator(object_list, 3) #每页3篇文章
            page = request.GET.get('page')
            try:
                posts = paginator.page(page)
            except PageNotAnInteger:
                posts = paginator.page(1)
            except EmptyPage:
                posts = paginator.page(paginator.num_pages)
            return render(request, 'blog/post/list.html', {'page': page, 'posts': posts})
      • paginator.page(self, number) : 返回第 number 页的数据内容
      • 不是整数就返回第一页,超过了最后一页的范围,就返回最后一页
      • 创建一个 pagination.html 模板,可以导入到任何其他模板中
      • templates 文件夹下创建
        <div class="pagination">
            <span class="step-links">
                <% if page.has_previous %>
                    <a href="?page={{ page.previous_page_number }}">Previous</a>
                <% endif %>
                <span class="current">
                    Page {{ page.number }} of {{ page.paginator.num_pages }}.
                </span>
                    {% if page.has_next %}
                        <a href="?page={{ page.next_page_number }}">Next</a>
                    {% endif %}
            </span>
        </div>
      • 这个模板中用了 page 对象
      • 返回到 blog/post/list.html 中,将上面的模板导入
        {% block content %}
            ...
            {% include "pagination.html" with page=posts %}
        {% endblock %}
      • 注意: pagination.html 文件放在 templates 文件夹根目录下
    • Using class-based views

      • 利用 Django 自带的基类来实现 post_list
      • 编辑 views.py
        from django.views.generic import ListView
      
        class PostListView(ListView):
            queryset = Post.published.all()
            context_object_name = 'posts'
            paginate_by = 3
            template_name = 'blog/post/list.html'
      • 指定了一个 QuerySet 来接受所有的 objects
      • 自定义查询结果命名为 context_object_name ,默认为 object_list
      • 分页结果显示3篇每页
      • 用指定的模板,默认为 blog/post_list.html
      • 之后,urls.py 中需要注释掉之前的 post_list URL pattern ,增加
        url(r'^$', views.PostListView.as_view(), name='post_list')
      
      • 为了保证控制分页的模板继续工作,blog/posts/list.html 中的 with page=posts 需要更改
      {% include "pagination.html" with page=page_obj %}
      
      • Django 中的 ListView 基类选择页面的参数名为 page_obj
      • 注意:使用 class 类 来实现了 之前的 def post_list 函数功能
    • ListView 类是显示对象列表,其中最重要的 getpost ,实际对应 http 中的 getpost 方法,as_view() 方法是处理 request-response 过程的接入点,在 urls.py中会被调用, dispatch() 方法就是上面提到的 getpost 方法