我們已經知道如何操作文章表的數據,接下來要將這些數據用界面顯示出來。這就需要用到django的view層負責處理http請求,並將數據傳給template模板進行渲染
url適配
首先定義列表頁與詳情頁的url, url規則如下:
django是怎麼知道將url映射到相應的python文件的?這需要我們在blog下新建urls.py文件
mysite/blog/urls.py
from django.urls import path from . import views app_name = 'blog' urlpatterns = [ path('', views.post_list, name='post_list'), # 列表頁的url規則 path('<int:year>/<int:month>/<int:day>/<slug:post>', # 詳情頁的url規則 views.post_detail, name='post_detail'), ]
然後需要在項目的urls.py中引入此文件:
mysite/mysite/urls.py
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('blog/', include('blog.urls', namespace='blog')) # 引入blog應用的url配置 ]
自定義模型管理器
封裝自定義的管理器,方便檢索數據。如,博客前臺要展示的數據肯定是已發佈的,如果每次取已發佈的數據都要通過過濾條件獲取,顯得很繁瑣。可以通過自定義管理器,將已發佈的文章封裝成文章類的一個屬性。
mysite/blog/models.py
class PublishedManager(models.Manager): def get_queryset(self): return super(PublishedManager, self).get_queryset().filter(status='published') class Post(models.Model): #... objects = models.Manager() # 默認的管理器 published = PublishedManager() # 自定義的管理器
以後我們只需要調用Post.published.all()
就能獲取所有已發佈的文章
在view中寫業務邏輯
mysite/blog/views.py
from django.shortcuts import render, get_object_or_404 from .models import Post # 列表頁 def post_list(request): posts = Post.published.all() # 獲取所有公開的文章 return render(request, 'blog/post/list.html', {'posts': posts}) # 將數據傳遞到模板文件 # 詳情頁 def post_detail(request, year, month, day, post): post = get_object_or_404(Post, slug=post, status='published', publish__year=year, publish__month=month, publish__day=day) return render(request, 'blog/post/detail.html', {'post': post})
在view中指定了list和detail的html文件路徑,我們需要在相應位置創建html文件:
新建模板文件
☁ mysite mkdir -p blog/templates/blog/post ☁ mysite touch blog/templates/blog/base.html ☁ mysite touch blog/templates/blog/post/list.html ☁ mysite touch blog/templates/blog/post/detail.html ☁ mysite tree blog/templates # 模板文件結構 blog/templates └── blog ├── base.html └── post ├── detail.html └── list.html 2 directories, 3 files
- base.html 定義了html模板的框架,列表頁和詳情頁都繼承此文件
- list.html 列表頁,展示文章標題、摘要
- detail.html 詳情頁,展示文章詳情內容
html模板引用 Bootstrap4
base.html
{% load static %} <!DOCTYPE html> <html> <head> <title>{% block title %}{% endblock %}</title> <link rel="stylesheet" href="{% static "css/blog.css" %}"> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.1.0/css/bootstrap.min.css"> <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/popper.js/1.12.5/umd/popper.min.js"></script> <script src="https://cdn.bootcss.com/bootstrap/4.1.0/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <div class="row"> <div id="content" class="col-md-9"> {% block content %} {% endblock %} </div> <div id="sidebar" class="col-md-3"> <h3>唐詩鑑賞博客</h3> <p>唐詩博大精深</p> </div> </div> </div> </body> </html>
在base.html中,我們引入了樣式文件{% static "css/blog.css" %}
,對應的路徑是:
mysite/blog/static/css/blog.css
.container { margin-top: 2%; } div.post { margin-bottom: 2%; }
關於模板語法的使用,詳情見官方文檔
list.html
{% extends "blog/base.html" %} {% block title %}我的博客{% endblock %} {% block content %} {% for post in posts %} <div class="post"> <h3> <a href="{{ post.get_absolute_url }}" class="text-info"> {{ post.title }} </a> </h3> <div class="card"> <div class="card-header"> 發佈時間:{{ post.publish }} 作者:{{ post.author }} </div> <div class="card-body"> {{ post.body|truncatewords:5|linebreaks }} </div> </div> </div> {% endfor %} {% endblock %}
list.html繼承了base.html, 並將內容注入到base.html中id爲content的div中
detail.html
{% extends "blog/base.html" %} {% block title %}{{ post.title }}{% endblock %} {% block content %} <h1>{{ post.title }}</h1> <div class="card"> <div class="card-header"> 發佈時間:{{ post.publish }} 作者:{{ post.author }} </div> <div class="card-body"> {{ post.body|linebreaks }} </div> </div> {% endblock %}
啓動服務,訪問 http://127.0.0.1:8000/blog/
列表頁
點擊列表頁的文章標題,進入詳情頁,注意查看詳情頁的url
http://127.0.0.1:8000/blog/2018/9/6/jiang-jin-jiu
詳情頁
添加分頁功能
如果我們的文章數據很多,不可能一次性全部取出,這時就需要做分頁功能。
首先自行到後臺多添加幾條數據
文章
在view中增加分頁邏輯
mysite/blog/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}) # 將數據傳遞到模板文件 # ...
分頁的樣式採用獨立的html頁面
新建 mysite/blog/templates/pagination.html
<ul class="pagination pagination-sm"> {% if page.has_previous %} <li class="page-item"><a class="page-link" href="?page={{ page.previous_page_number }}">上一頁</a></li> {% endif %} <li class="page-item active"><a class="page-link" href="#">{{ page.number }}</a></li> {% if page.has_next %} <li class="page-item"><a class="page-link" href="?page={{ page.next_page_number }}">下一頁</a></li> {% endif %} </ul>
在列表頁中引入分頁
mysite/blog/templates/blog/post/list.html
{% block content %} # ... {% include "pagination.html" with page=posts %} {% endblock %}
瀏覽器訪問 http://127.0.0.1:8000/blog/
分頁
點擊下一頁,查看url的變化:http://127.0.0.1:8000/blog/?page=2
至此,簡易的分頁功能已完成
下一節將講解如何使用django發送郵件。如果你感興趣,請關注我的django2實戰
文集
如果覺得本文對你有所幫助,點個贊,或者賞杯咖啡錢,你的認可對我很重要