Assessment: DIY Django mini blog
在這個評估中,你將使用你在 Django Web Framework (Python) 模組中獲得的知識,來創建一個非常基本的部落格。
前提: |
在開始時做這章節的任務之前,你應該已經看完這個模組的所有文章了。 |
---|---|
目標: |
測試Django基礎的綜合應用,包含URL設定、模型、視圖、表單和模板。 |
專案簡介
需要顯示的頁面與對應的 URLs 和需求提列於下表:
頁面 | URL | 需求 |
---|---|---|
首頁 | / 和 /blog/ |
關於此站的說明。 |
所有部落格文章的清單 | /blog/blogs/ |
所有部落格文章的清單。
|
部落格作者(blogger) 詳細頁面 | /blog/blogger/<author-id> |
特定作者(由id指定)的資訊與他所發布的部落格文章。
|
部落格文章詳細頁面 | /blog/<blog-id> |
部落格文章詳細內容。
|
部落格作者清單 | /blog/bloggers/ |
系統內的部落格作者清單。
|
回覆表單頁 | /blog/<blog-id>/create |
新增回覆於特定文章。
|
使用者身分認證頁 | /accounts/<standard urls> |
標準的Django身分驗證頁面,用來登入、登出及修改密碼。
|
管理者網頁 | /admin/<standard urls> |
管理者網頁必須能新增/編輯/刪除部落格文章、作者及回覆。
|
另外你應該要寫一些基本的測試來驗證:
- 所有的模型欄位都有正確的標示和長度。
- 所有的模型都有期望的物件名稱(例如
__str__()
回傳期望的值)。 - 模型有期望的 URL 給每篇文章與回覆。(例如
get_absolute_url()
回傳期望的 URL)。 - BlogListView (所有文章的頁面) 可以從期望的位址進入(例如/blog/blogs)。
- BlogListView (所有文章的頁面) 可以從期望的位址名稱進入(例如'blogs')。
- BlogListView (所有文章的頁面) 使用期望的模板(例如預設值)。
- BlogListView 以每頁 5 筆項目分頁(至少第一頁是如此)。
備註:當然你也可以跑很多其他的測試。但是我們會希望你至少實作以上列出的測試項目。
下一區塊顯示符合以上需求的網頁截圖。
截圖
The following screenshot provide an example of what the finished program should output.
列出所有的部落格文章
這個頁面會列出所有部落格內的文章(可以從側邊選單的「所有文章」連結進入)。 幾項提醒:
- 側邊選單也要列出目前登入的使用者。
- 每篇文章與部落客都能透過連結的方式進入。
- 必須要有分頁(每頁 5 筆資料)。
- 文章排列順序由最新至最舊。
列出所有部落客(文章作者)
可以由側邊選單的「所有部落客」進入此頁面,並於頁面上提供連結至每一位部落客。 從截圖可以發現到,並沒有任何一位使用者登入。
部落格詳細頁
顯示某篇特定部落格文章的詳細內容。
請注意每個評論都有日期與時間,並且由最後至最新排列(與部落格文章相反)。 我們可以看見最底下有個連結連到新增評論的表單。當使用者沒有登入時,我們改以要求登入的連結代替。
新增評論表單
這張表單用來新增評論,且使用者必須是登入狀態。當表單送出成功之後,我們必須回到相對應的部落格文章內容頁。
作者資料
這頁顯示部落客的介紹資料以及列出他們所發表的部落格文章。
一步一腳印 Steps to complete
以下說明實作的步驟。
-
建立一個此網站的專案及 app 骨架(可以參考Django 教學 2 : 建立一個網站骨架)。你也許會用『diyblog』作為專案名稱,『blog』作為 app 的名稱。
-
建立部落格文章、評論與其他任何所需物件的模型。當你在思考怎麼設計的時候,請記得:
- 每一個評論都只屬於一篇部落格文章,但每一個部落格文章可以有很多筆評論。
- 部落格文章必須要依照發布時間排序(新至舊),評論要依照發布排序(舊至新)。
- 不是每位使用者都是部落客,但是每一位使用者都可以留下評論。
- 部落客必須有介紹資訊。
-
跑 migrations 以及創建一個新的超級使用者(superuser)。
-
透過 admin 網站新稱一些部落格文章和評論。
-
幫部落格文章列表頁與部落客列表頁建立視圖、模板及設定 URL。
-
幫部落格文章詳細頁與部落客詳細頁建立視圖、模板及設定 URL。
-
建立一個頁面包含可以新增評論的表單(記得只有已登入的使用者可以進入此頁!)
提示與小技巧
This project is very similar to the LocalLibrary tutorial. You will be able to set up the skeleton, user login/logout behaviour, support for static files, views, URLs, forms, base templates and admin site configuration using almost all the same approaches.
Some general hints:
-
The index page can be implemented as a basic function view and template (just like for the locallibrary).
-
The list view for blog posts and bloggers, and the detail view for blog posts can be created using the generic list and detail views.
-
The list of blog posts for a particular author can be created by using a generic list Blog list view and filtering for blog object that match the specified author.
- You will have to implement
get_queryset(self)
to do the filtering (much like in our library classLoanedBooksAllListView
) and get the author information from the URL. - You will also need to pass the name of the author to the page in the context. To do this in a class-based view you need to implement
get_context_data()
(discussed below).
- You will have to implement
-
The add comment form can be created using a function-based view (and associated model and form) or using a generic
CreateView
. If you use aCreateView
(recommended) then:-
You will also need to pass the name of the blog post to the comment page in the context (implement
get_context_data()
as discussed below). -
The form should only display the comment "description" for user entry (date and associated blog post should not be editable). Since they won't be in the form itself, your code will need to set the comment's author in the
form_valid()
function so it can be saved into the model (as described here — Django docs). In that same function we set the associated blog. A possible implementation is shown below (pk
is a blog id passed in from the URL/URL configuration).pythondef form_valid(self, form): """ Add author and associated blog to form data before setting it as valid (so it is saved to model) """ #Add logged-in user as author of comment form.instance.author = self.request.user #Associate comment with blog based on passed id form.instance.blog=get_object_or_404(Blog, pk = self.kwargs['pk']) # Call super-class form validation behaviour return super(BlogCommentCreate, self).form_valid(form)
-
You will need to provide a success URL to redirect to after the form validates; this should be the original blog. To do this you will need to override
get_success_url()
and "reverse" the URL for the original blog. You can get the required blog ID using theself.kwargs
attribute, as shown in theform_valid()
method above.
-
We briefly talked about passing a context to the template in a class-based view in the Django Tutorial Part 6: Generic list and detail views topic. To do this you need to override get_context_data()
(first getting the existing context, updating it with whatever additional variables you want to pass to the template, and then returning the updated context). For example, the code fragment below shows how you can add a blogger object to the context based on their BlogAuthor
id.
class SomeView(generic.ListView):
...
def get_context_data(self, **kwargs):
# Call the base implementation first to get a context
context = super(SomeView, self).get_context_data(**kwargs)
# Get the blogger object from the "pk" URL parameter and add it to the context
context['blogger'] = get_object_or_404(BlogAuthor, pk = self.kwargs['pk'])
return context
Assessment
The assessment for this task is available on Github here. This assessment is primarily based on how well your application meets the requirements we listed above, though there are some parts of the assessment that check your code uses appropriate models, and that you have written at least some test code. When you're done, you can check out our the finished example which reflects a "full marks" project.
Once you've completed this module you've also finished all the MDN content for learning basic Django server-side website programming! We hope you enjoyed this module and feel you have a good grasp of the basics!