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