[Django 30Days] Day10 Blog實作範例一文章列表、內容與分類
Day10 部落格文章列表、內容、分類製作。
這篇要來製作部落格首頁的文章列表,當使用者看到有興趣的文章,點選繼續閱讀則跳網此文章的內容頁面。
1.規劃好URL
2. 將URL與View對應並設計View。
3.編寫Template並讓VIew渲染Template。
URL部分:
#myblog/urls.py
from django.urls import path
from myblog.views import *urlpatterns = [
path('post/', PostListView.as_view()),
path('post/<int:pk>', PostDetailView.as_view()),
path('post/category/<int:pk>', PostCategoryView.as_view()),]
post頁面呈現文章列表。
post/<int:pk> url會取文章的primary key當url,
ex:當使用者點選第二篇文章的繼續閱讀時就會進入,被括起來的pk會匹配此篇文章的id,這pk會在調用PostDetailView時被傳遞進去,實際調用
def get(self, request, pk=2)。
View文章列表及詳情部分:
#myblog/views.py
from django.views import View
from django.shortcuts import render,get_object_or_404
from myblog.models import *class PostListView(View):
template_name = 'myblog/post_list.html'
def get(self, request, *args, **kwargs):
post_list = BlogPost.objects.all().order_by("-created_at")
category_list = BlogPostCategory.objects.all()
return render(request, self.template_name, locals())class PostDetailView(View):
template_name = 'myblog/post_detail.html'
def get(self, request, pk):
post = get_object_or_404(BlogPost, pk=pk)
category_list = BlogPostCategory.objects.all()
return render(request, self.template_name, locals())class PostCategoryView(View):
template_name = 'myblog/post_category.html'
def get(self, request, pk):
category = get_object_or_404(BlogPostCategory, pk=pk)
posts_by_category = BlogPost.objects.filter(category=category)
post_by_categories = category
return render(request, self.template_name, locals())"""
locals()用法:
會將View中所有變數傳到Templates中,若有多餘的變數則會浪費內存。get_object_or_404用法:
當傳來的pk對應BlogPost值存在時就回傳post,否則就回傳error給使用者表示文章不存在。
"""
PostListView:
使用all()方法取得DB中所有文章,存在post_list中。all方法回傳的是一個QuerySet(類似List),而一般Blog 文章最新的會在最前面,因此使用order_by對文章建立時間排序,最後locals()將post_list與category_list傳到myblog/post_list.html中渲染。
PostDeatilView:
1.根據URL中的文章id抓DB中的文章id。
2.取出所有category。
3.回傳template。
PostCategoryView:
當使用者在post_list.html頁面點選分類名稱時候會進入,此分類列表。
1.依照pk取出類別。
2.根據類別過濾分類後的文章。
3.回傳template。
Template:
base.html微調整1.標題改寫可以繼承<title>{% block title %} {% endblock %}</title>2.找到首頁的地方並加/myblog/post連結
<li class="nav-item active">
<a class="nav-link" href="/myblog/post/">首頁<span class="sr-only"> (current)</span></a>
</li>
myblog/post_list.html
行3:{% extends 'base.html' %} 延伸基層的模板,
並加內容添加在 {% block content%} {% endblock %}中。行18~20:利用filter計算總共有幾篇文章,並在https://getbootstrap.com/docs/4.5/components/alerts/
利用alert框框美化。行40:設定對應分類列表的url。利用{% for post in post_list %} 迭代views傳過來的變數post_list,若無文章則為empty暫無文章,敬請期待。
依序排序要呈現的內容,
title 文章標題
author.username 作者
category.name 類別
created_at 發文時間
summary 摘要
並將繼續閱讀設定文章id。
myblog/post_detail.html
點選繼續閱讀後可以點進來呈現內容部分。
title 文章標題
author.username 作者
category.name 類別
created_at 發文時間
content 內容
行5~7:class alert將美化title部分。行10:設定對應分類列表的url。
myblog/post_category.html
行9~12:美化分類名稱及文章統計。
行14~16利用標題當超連結連到文章內容頁。
行19:將文章內容簡化成三十字以內。
Built-in template tags and filters:
Django中不論是在templates中利用tags對傳入html的變數做判斷{% if condition %} … {% elif condition %} … {% endif %}或者filter {{ msg| upper}將傳入html的字串全變大寫等,都有許多方法支援。
ex:
1.{{ value }}直接顯示值
2.遇到dict格式{{ test.value }}
3.若遇到內容較多的list或有些資訊希望有資料才顯示、沒資料就不顯示,就需要更多語法才能應付。
雖然template可以做迴圈、判斷式、過濾器等,但只用來處理資料顯示即可,過於複雜的邏輯盡量放在views.py。
tags ex:
{% extends 'base'.html %}filter ex: post_list.html post_detail.html中的發文時間。
<a href=”#”>{{ post.created_at|date:’Y-m-d h:m:s’ }}</a>
即為將格式轉為 2020-01-09 11:20:55
Django部分filter:
若是想要了解或是查詢更多好用的tags與filter可以前往django的documatation查詢。
以下我們的初版誕生。
首頁 /myblog/post/
內容頁/myblog/post/2
Reference:
django tags and filter
何敏煌 — Python新手使用django架站技術實作