摘要:一些表單界面元素文本框或復(fù)選框非常簡單并內(nèi)置在中,而其他會復(fù)雜些像彈出日期選擇等操作控件。和標(biāo)簽中的屬性指定了當(dāng)前文本框提交的數(shù)據(jù)的名稱,它必須與表單類中的字段名稱對應(yīng),否則服務(wù)器無法將字段和數(shù)據(jù)正確的對應(yīng)起來。
前面我們已經(jīng)學(xué)會如何用Markdown語法書寫文章了。
但是還有問題呀。之前寫文章都是在后臺中進行的,萬一有別的普通用戶也要發(fā)表文章怎么辦?萬一我想拓展些后臺中沒有的提交驗證功能又怎么辦?
本章即講述如何在前臺中提交新的文章,以便滿足開發(fā)者各種各樣的特殊需求。
Forms表單類在HTML中,表單是在 中的一些元素,它允許訪客做類似輸入文本、選擇選項、操作對象或空間等動作,然后發(fā)送這些信息到服務(wù)端。一些表單界面元素(文本框或復(fù)選框)非常簡單并內(nèi)置在HTML中,而其他會復(fù)雜些:像彈出日期選擇等操作控件。
處理表單是一件挺復(fù)雜的事情。想想看Django的admin,許多不同類型的數(shù)據(jù)可能需要在一張表單中準(zhǔn)備顯示,渲染成HTML,使用方便的界面進行編輯,傳到服務(wù)器,驗證和清理數(shù)據(jù),然后保存或跳過進行下一步處理。
Django的表單功能可以簡化上述工作的大部分內(nèi)容,并且也能比大多數(shù)程序員自己編寫代碼去實現(xiàn)來的更安全。
Django表單系統(tǒng)的核心組件是 Form類,它能夠描述一張表單并決定它如何工作及呈現(xiàn)。
要使用Form類也很簡單,需要在article/中創(chuàng)建forms.py文件,并寫入如下代碼:
article/forms.py # 引入表單類 from django import forms # 引入文章模型 from .models import ArticlePost # 寫文章的表單類 class ArticlePostForm(forms.ModelForm): class Meta: # 指明數(shù)據(jù)模型來源 model = ArticlePost # 定義表單包含的字段 fields = ("title", "body")
代碼中ArticlePostForm類繼承了Django的表單類forms.ModelForm,并在類中定義了內(nèi)部類class Meta(之前提到過,還記得嗎),指明了數(shù)據(jù)模型的來源,以及表單中應(yīng)該包含數(shù)據(jù)模型的哪些字段。
在ArticlePost模型中,created和updated字段為自動生成,不需要填入;author字段暫時固定為id=1的管理員用戶,也不用填入;剩下的title和body就是表單需要填入的內(nèi)容了。
接下來,改寫article/views.py,添加一個視圖函數(shù)以處理寫文章的請求:
article/views.py ... # 引入redirect重定向模塊 from django.shortcuts import render, redirect # 引入HttpResponse from django.http import HttpResponse # 引入剛才定義的ArticlePostForm表單類 from .forms import ArticlePostForm # 引入User模型 from django.contrib.auth.models import User ... # 寫文章的視圖 def article_create(request): # 判斷用戶是否提交數(shù)據(jù) if request.method == "POST": # 將提交的數(shù)據(jù)賦值到表單實例中 article_post_form = ArticlePostForm(data=request.POST) # 判斷提交的數(shù)據(jù)是否滿足模型的要求 if article_post_form.is_valid(): # 保存數(shù)據(jù),但暫時不提交到數(shù)據(jù)庫中 new_article = article_post_form.save(commit=False) # 指定數(shù)據(jù)庫中 id=1 的用戶為作者 new_article.author = User.objects.get(id=1) # 將新文章保存到數(shù)據(jù)庫中 new_article.save() # 完成后返回到文章列表 return redirect("article:article_list") # 如果數(shù)據(jù)不合法,返回錯誤信息 else: return HttpResponse("表單內(nèi)容有誤,請重新填寫。") # 如果用戶請求獲取數(shù)據(jù) else: # 創(chuàng)建表單類實例 article_post_form = ArticlePostForm() # 賦值上下文 context = { "article_post_form": article_post_form } # 返回模板 return render(request, "article/create.html", context)
分析一下上面的代碼。當(dāng)視圖函數(shù)接收到一個客戶端的request請求時,首先根據(jù)request.method判斷用戶是要提交數(shù)據(jù)(POST)、還是要獲取數(shù)據(jù)(GET):
如果用戶是提交數(shù)據(jù),將POST給服務(wù)器的表單數(shù)據(jù)賦于article_post_form實例。
然后使用Django內(nèi)置的方法.is_valid()判斷提交的數(shù)據(jù)是否滿足模型的要求。
如果滿足要求,保存表單中的數(shù)據(jù)(但是commit=False暫時不提交到數(shù)據(jù)庫,因為author還未指定),并指定author為id=1的管理員用戶。然后提交到數(shù)據(jù)庫,并通過redirect返回文章列表。redirect可通過url地址的名字,反向解析到對應(yīng)的url。
如果不滿足要求,則返回一個字符串"表單內(nèi)容有誤,請重新填寫。",告訴用戶出現(xiàn)了什么問題。
如果用戶是獲取數(shù)據(jù),則返回一個空的表單類對象,提供給用戶填寫。
其實邏輯并不復(fù)雜,不明白的讀者請逐句理解。
這里特別提醒Django中的縮進不能夠空格和tab鍵混用,否則會報錯。由于不同的編輯器對tab的顯示不盡相同,因此你應(yīng)該堅持使用空格鍵縮進。
寫好視圖之后,就需要寫模板文件了。在templates/article/中創(chuàng)建create.html:
templates/article/create.html {% extends "base.html" %} {% load staticfiles %} {% block title %} 寫文章 {% endblock title %} {% block content %}{% endblock content %}
html文件還是一如既往的長。再重復(fù)一次,看不懂html文件語法也沒有關(guān)系,先照著抄一遍,以后再慢慢理解,不影響目前Django的學(xué)習(xí)。
對其中的新內(nèi)容進行審視:
標(biāo)簽中的內(nèi)容就是需要提交的表單。method="post"指定了表單提交的方式為POST(與視圖函數(shù)中的request.method相聯(lián)系);action="."指定了表單提交的地址為默認(rèn)的當(dāng)前url。
關(guān)于{% csrf_token %},它是Django中一個與網(wǎng)絡(luò)安全相關(guān)的中間件驗證。目前我們暫時不去深究它的實現(xiàn),只需要知道表單中必須包含它就可以了,否則將會得到一個403錯誤。
和標(biāo)簽中的name=""屬性指定了當(dāng)前文本框提交的數(shù)據(jù)的名稱,它必須與表單類中的字段名稱對應(yīng),否則服務(wù)器無法將字段和數(shù)據(jù)正確的對應(yīng)起來。
最后老規(guī)矩,在article/urls.py中增加一個寫文章的url地址:
article/urls.py urlpatterns = [ ... # 寫文章 path("article-create/", views.article_create, name="article_create"), ]
大功告成了,不要著急,先喝口水,萬一有bug又得忙活半天了。如果報錯也不要慌張,開發(fā)過程一定是曲折的,耐心看看Django給出的錯誤提示,線索就在其中。
保存修改并運行服務(wù)器,地址欄中輸入:http://127.0.0.1:8000/article/article-create/,看到如下界面:
很好,似乎正常工作起來了。接著隨便輸入些Markdown語法的文章,測試功能是否正常:
點擊完成按鈕后,頁面會回到文章列表:
剛才提交的文章神奇的出現(xiàn)在列表中了。
點擊閱讀本文按鈕,進入文章詳情頁面:
出現(xiàn)了具有Markdown語法的一篇優(yōu)美的文章。
使用Django編寫博客是不是非常有成就感呢?
別激動,還有一些收尾工作需要做。
優(yōu)化寫文章入口與之前類似,我們需要在導(dǎo)航欄中設(shè)置一個寫文章的入口,優(yōu)化使用體驗。
將下列代碼加入到templates/header.html中:
讀者是否清楚,上面的代碼應(yīng)該放置在什么位置呢?
保存后刷新瀏覽器界面,導(dǎo)航欄有了如下變化:
點擊寫文章按鈕,就可以進入寫新文章的頁面了,從此再也不用手動輸入繁瑣的url地址了。
世界是多么的美好。
總結(jié)本章學(xué)習(xí)了使用Django的表單類,完成了提交新文章的基本功能。當(dāng)然目前暫時還沒有真正將文章和登錄的用戶關(guān)聯(lián)起來;等到學(xué)習(xí)了用戶管理的知識,再回頭來處理這部分的內(nèi)容。
下一章繼續(xù)學(xué)習(xí)如何刪除一篇文章。
有疑問請在杜賽的個人網(wǎng)站留言,我會盡快回復(fù)。
或Email私信我:dusaiphoto@foxmail.com
項目完整代碼:Django_blog_tutorial
轉(zhuǎn)載請告知作者并注明出處。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/42531.html
摘要:最常見的用法就是存儲用戶的登錄數(shù)據(jù)。如果用戶未登錄,則顯示登錄兩個字提醒用戶可以點擊登錄。創(chuàng)建文件用戶登錄配置根路由用戶管理配置因為這個并沒有改動,因此不用遷移數(shù)據(jù)??偨Y(jié)本章用到了表單類模板語句用戶驗證等知識完成了用戶管理的登錄和退出。 用戶管理 用戶數(shù)據(jù)可以說是大部分網(wǎng)站最重要的資產(chǎn)。用戶管理就是對用戶數(shù)據(jù)進行增刪改查等操作的功能,自然也就非常的重要了。 本章開始學(xué)習(xí)用戶管理的內(nèi)容,...
摘要:確認(rèn)創(chuàng)建成功后,記得在中注冊因為我們想顯示發(fā)表評論的時間,修改時區(qū)設(shè)置為上海的時區(qū)。處理錯誤請求發(fā)表評論僅接受請求。返回到一個適當(dāng)?shù)闹屑从脩舭l(fā)送評論后,重新定向到文章詳情頁面。總結(jié)本章實現(xiàn)了發(fā)表評論展示評論的功能。 在沒有互聯(lián)網(wǎng)的年代,我們用日記來記錄每天的心得體會。小的時候我有一個帶鎖的日記本,生怕被別人看見里面寫了啥,鑰匙藏得那叫一個絕。 現(xiàn)在時代變了,網(wǎng)絡(luò)版的日記本:博客,卻巴不...
摘要:下一步就是修改視圖。判斷語句的條件有兩個博文的標(biāo)題圖不是必須的,剔除掉沒有標(biāo)題圖的文章,這些文章不需要處理圖片。總結(jié)本章學(xué)習(xí)了如何上傳并處理文章的標(biāo)題圖,從此博客首頁就有了漂亮的外觀。 現(xiàn)在雖然博客的功能大都實現(xiàn)了,但是界面還是比較樸素,特別是首頁的文章列表幾乎全是文字,看多了難免疲勞。因此,給每個文章標(biāo)題配一張標(biāo)題圖,不僅美觀,用戶也能通過圖片快速了解文章內(nèi)容。實際上大部分社交網(wǎng)站也...
摘要:既然有登錄登出,那么用戶的注冊肯定也是少不了的。用戶在注冊成功后會自動登錄并返回博客列表頁面??偨Y(jié)本章用到了表單類對數(shù)據(jù)進行驗證清洗等知識,完成了用戶的注冊功能。 既然有登錄登出,那么用戶的注冊肯定也是少不了的。 注冊表單類 用戶注冊時會用到表單來提交賬號、密碼等數(shù)據(jù),所以需要寫注冊用的表單/userprofile/forms.py: /userprofile/forms.py .....
摘要:每一篇文章的標(biāo)簽可能都不一樣,并且還可能擁有多個標(biāo)簽,這是與欄目功能不同的。列表中顯示標(biāo)簽雖然保存標(biāo)簽的功能已經(jīng)實現(xiàn)了,還得把它顯示出來才行。更多的用法請閱讀官方文檔總結(jié)本章學(xué)習(xí)了使用來完成標(biāo)簽功能。 標(biāo)簽是作者從文章中提取的核心詞匯,其他用戶可以通過標(biāo)簽快速了解文章的關(guān)注點。每一篇文章的標(biāo)簽可能都不一樣,并且還可能擁有多個標(biāo)簽,這是與欄目功能不同的。 好在標(biāo)簽功能也有優(yōu)秀的三方庫:D...
閱讀 3472·2019-08-30 15:44
閱讀 812·2019-08-30 13:46
閱讀 2105·2019-08-30 11:05
閱讀 3348·2019-08-29 18:32
閱讀 2168·2019-08-29 13:56
閱讀 1306·2019-08-29 12:57
閱讀 772·2019-08-28 18:21
閱讀 1761·2019-08-26 12:16