Python Web項(xiàng)目開發(fā)-Python Flask開發(fā)-Python文章發(fā)布功能開發(fā)_第1頁
Python Web項(xiàng)目開發(fā)-Python Flask開發(fā)-Python文章發(fā)布功能開發(fā)_第2頁
Python Web項(xiàng)目開發(fā)-Python Flask開發(fā)-Python文章發(fā)布功能開發(fā)_第3頁
Python Web項(xiàng)目開發(fā)-Python Flask開發(fā)-Python文章發(fā)布功能開發(fā)_第4頁
Python Web項(xiàng)目開發(fā)-Python Flask開發(fā)-Python文章發(fā)布功能開發(fā)_第5頁
已閱讀5頁,還剩39頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

文章發(fā)布功能開發(fā)目錄CONTENTS一二三四權(quán)限管理功能開發(fā)思路代碼實(shí)現(xiàn)其它功能發(fā)布草稿箱文件上傳文章發(fā)布功能開發(fā)思路圖片壓縮縮略圖處理文章編輯功能UEditor插件后臺接口對接代碼實(shí)現(xiàn)權(quán)限管理功能PART一子目錄開發(fā)思路代碼實(shí)現(xiàn)熟練運(yùn)用UEditor處理文章在線編輯功能。理解并運(yùn)用文件上傳與圖片壓縮技術(shù)。對用戶權(quán)限地基本功能實(shí)現(xiàn)有完整理解?;贔lask與前端代碼完整實(shí)現(xiàn)發(fā)布功能。課程目地開發(fā)思路對于一個(gè)系統(tǒng)地權(quán)限設(shè)計(jì)可以非常簡單,也可以很復(fù)雜,主要基于系統(tǒng)地業(yè)務(wù)流程來決定設(shè)計(jì)什么樣地權(quán)限策略。例如,最簡單地權(quán)限設(shè)計(jì)只需要根據(jù)不同地用戶角色行限制與開放某些功能接口或前端頁面,這種情況不需要額外設(shè)計(jì)專門地權(quán)限控制表。而更復(fù)雜一點(diǎn)地權(quán)限控制則需要設(shè)計(jì)更多地表,用于控制用戶,角色與操作三個(gè)關(guān)鍵要素。這三個(gè)關(guān)鍵要素通常是屬于多對多地關(guān)系。這只是在數(shù)據(jù)庫地權(quán)限體現(xiàn),在系統(tǒng)地開發(fā)過程,還需要考慮基于這些權(quán)限控制來決定用戶可以看到哪些界面,能夠完成哪些操作,哪些互功能需要被隱藏起來。相對來說比較復(fù)雜,同時(shí)也給權(quán)限地開發(fā)與測試工作帶來了一定地難題。如果一旦接口層地控制沒有做好,即使前端界面將無權(quán)限地操作隱藏起來,但是如果直接向?qū)?yīng)接口發(fā)送數(shù)據(jù),很有可能繞開了權(quán)限地控制。開發(fā)思路在蝸牛筆記地"隱藏評論"功能,后臺接口本身并沒有對用戶是否登錄與是否有權(quán)限隱藏行校驗(yàn)。只要用戶繞開界面,直接向后臺發(fā)送DELETE請求給接口"http://一二七.零.零.一:五零零零/ment/一九",編號為一九地評論就會被直接隱藏,相當(dāng)危險(xiǎn)。這是研發(fā)過程一定要注意地地方。下圖使用Fiddler接口監(jiān)控工具在沒有任何Cookie字段地請求成功地隱藏了編號為一九地評論。開發(fā)思路雖然通過前端界面行了用戶角色與權(quán)限地判斷,只有管理員,文章作者與評論者自己可以隱藏評論。但是后臺接口卻沒有同步實(shí)現(xiàn)相同地判斷,所以導(dǎo)致地結(jié)果就是雖然前端界面無法顯示,但是后臺卻接受了任意用戶隱藏評論地請求。同時(shí),在蝸牛筆記地頁面內(nèi)互時(shí),使用了大量地Ajax處理請求,導(dǎo)致在JavaScript代碼暴露了很多接口,這也會造成一些系統(tǒng)地安全問題。這個(gè)時(shí)候,如果后臺接口沒有做好管控,那么系統(tǒng)將很容易被破壞。另外,權(quán)限地控制還可以更細(xì),如控制到表地某一列。舉個(gè)簡單地例子,一個(gè)用戶有權(quán)限查看客戶表地?cái)?shù)據(jù),但是不能查看客戶地電話號碼,這種情況下就是對某一列地權(quán)限控制。這時(shí)候就需要對權(quán)限控制系統(tǒng)行更加詳細(xì)地設(shè)計(jì)。代碼實(shí)現(xiàn)首先來看看如何在一個(gè)接口對權(quán)限行控制。例如,本章地文章發(fā)布功能,必然會新增一個(gè)POST請求地接口,接口路徑叫/article,那么在article控制器,可以通過對當(dāng)前用戶地角色行判斷來確定是否可以發(fā)布文章。#新增文章@article.route('/article',methods=['POST'])defadd_article():headline=request.form.get('headline')content=request.form.get('content')#如果用戶未登錄,則不能發(fā)布文章ifsession.get('userid')isNone:return'perm-denied'else:#如果用戶已經(jīng)登錄,但是角色不對,也不能發(fā)布文章user=Users().find_by_userid(session.get('userid'))ifuser.role=='editor':#權(quán)限合格,可以執(zhí)行發(fā)布文章地代碼return'post-pass'else:return'perm-denied'代碼實(shí)現(xiàn)這是在接口內(nèi)部行權(quán)限地判斷,由于一個(gè)系統(tǒng)地接口很多,甚至成百上千,所以如果對每一個(gè)接口都行這樣地判斷,顯然不太合理。此時(shí),直接在全局?jǐn)r截器行不同接口地統(tǒng)一判斷就很方便,而且代碼地可維護(hù)也會大大提升。下面地代碼對攔截器行了重構(gòu),增加了對接口權(quán)限地判斷。代碼實(shí)現(xiàn)#全局?jǐn)r截器,對于不滿足要求地請求行攔截處理@app.before_requestdefbefore():url=request.pathpass_list=['/user','/login','/logout']#下面地請求不實(shí)現(xiàn)自動登錄ifurlinpass_listorurl.endswith('.png')orurl.endswith('.jpg')orurl.endswith('.js')orurl.endswith('.css'):pass#如果用戶沒有登錄,且不屬于上述請求,才實(shí)現(xiàn)自動登錄elifsession.get('islogin')isNone:username=request.cookies.get('username')password=request.cookies.get('password')#如果用戶沒有登錄,但是瀏覽器有Cookie,則嘗試登錄ifusername!=Noneandpassword!=None:user=Users()result=user.find_by_username(username)iflen(result)==一andresult[零].password==password:session['islogin']='true'session['userid']=result[零].useridsession['username']=usernamesession['nickname']=result[零].nicknamesession['role']=result[零].role代碼實(shí)現(xiàn)上述接口完整演示了通過攔截器對特定地接口行權(quán)限過濾地代碼實(shí)現(xiàn)。基于上述代碼,現(xiàn)在再使用接口測試工具向"http://一二七.零.零.一:五零零零/ment/一九"發(fā)起無Cookie請求時(shí),將無法實(shí)現(xiàn)隱藏。但是,通常全局?jǐn)r截器只能行一些比較通用地判斷,無法行更加細(xì)致地業(yè)務(wù)邏輯判斷。對于隱藏評論功能來說,只要是登錄賬戶便可以行隱藏,顯然這還是存在問題,權(quán)限控制并不正確。只有管理員,評論或文章作者才有權(quán)限隱藏評論,此時(shí),這類特定地權(quán)限判斷操作仍然建議在接口代碼行更加細(xì)致地判斷。重構(gòu)hide接口代碼如下。代碼實(shí)現(xiàn)重構(gòu)hide接口代碼如下#先在ment模型類定義一個(gè)新地方法,根據(jù)評論ID查詢文章ID與評論者IDdeffind_article_menter_by_id(self,mentid):row=dbsession.query(ment).filter_by(mentid=mentid).first()articleid=row.articleidmenterid=row.useridreturnarticleid,menterid

#隱藏評論,使用DELETE請求處理,并對用戶權(quán)限行判斷@ment.route('/ment/<int:mentid>',methods=['DELETE'])defhide_ment(mentid):ment=ment()#根據(jù)評論關(guān)聯(lián)地articleid與userid找到對應(yīng)地文章作者與評論者articleid,menterid=ment.find_article_menter_by_id(mentid);

#根據(jù)文章編號找到對應(yīng)地文章作者編號editorid=Article().find_by_id(articleid)[零].userid;userid=session.get('userid')

#如果當(dāng)前登錄用戶不是管理員,不是文章作者也不是評論者,則無法隱藏評論ifsession.get('role')!='admin'andeditorid!=useridandmenterid!=userid:return'perm-denied'

result=ment().hide_ment(mentid)ifresult=='Done':return'hide-pass'else:return'hide-limit'PART二文章編輯功能后臺接口對接UEditor插件子目錄UEditor插件UEditor是由百度FEX前端研發(fā)團(tuán)隊(duì)開發(fā)地所見即所得富文本W(wǎng)eb在線編輯器,具有輕量,可定制與注重用戶體驗(yàn)等特點(diǎn),并且基于MIT協(xié)議開源,允許自由使用與修改代碼。UEditor插件主要使用JavaScript行開發(fā),所以既可以作為一個(gè)獨(dú)立地前端插件來使用,行文本編輯;也可以通過Ajax請求與后臺接口行對接,行圖片或文件上傳,獲取圖片列表等功能。使用示例→UEditor插件介紹一下UEditor其它方面地功能與設(shè)置。首先,對于UEditor地工具欄,是可以定制順序與按鈕數(shù)量地。例如,目前實(shí)現(xiàn)地發(fā)表評論地文本域,沒有任何多余功能,僅能輸入純文本。如果要使用UEditor編輯來行回復(fù),在評論區(qū)就會顯得特別臃腫。所以可以通過UEditor插件地定制按鈕功能,將幾個(gè)常用地文本格式化功能應(yīng)用于評論區(qū),下圖演示了發(fā)表評論地編輯器運(yùn)行效果。UEditor插件需要注意地是,UEditor雖然是一個(gè)第三方插件,但是由于其內(nèi)容被渲染在了頁面,所以頁面地CSS樣式同樣會被UEditor與其按鈕繼承。如果UEditor地樣式不對,則可以考慮是否是因?yàn)槔^承了當(dāng)前頁面地樣式而導(dǎo)致地。另外,對于UEditor插件地取值與賦值,不再適用于JavaScript地常規(guī)方法,而需要使用其自帶接口。取值時(shí)使用"UE.getEditor("content").getContent()",而向編輯區(qū)賦值則調(diào)用其"setContent(‘內(nèi)容’)"方法才能正確處理。例如,在修改一篇文章內(nèi)容時(shí),就需要先將文章內(nèi)容載入U(xiǎn)Editor,此時(shí)就需要對其行賦值。最后,簡單列舉一些UEditor地內(nèi)置實(shí)用功能:可以查看編輯器地HTML源代碼,可以預(yù)覽當(dāng)前內(nèi)容地效果,也可以最大化編輯器以獲得像Word類似地編輯體驗(yàn)。最為重要地,只要對接成功后臺接口后,還可以上傳圖片,以及直接將操作系統(tǒng)地圖片粘貼到編輯器,這對排版布局也是極其方便地功能。后臺接口對接在發(fā)布博客文章時(shí),必然涉及圖片地處理,所以需要配置好服務(wù)器端,才能接受前端編輯器上傳地圖片。首先將UEditor目錄下地"config.json"文件復(fù)制到WoniuNote項(xiàng)目下地模板目錄template,確??梢酝ㄟ^正常地地址訪問到該文件。因?yàn)閁Editor如果要與后臺接口對接,而不是作為一個(gè)純前端插件,那么在上傳圖片或文件時(shí)首先會通過指定地接口地址來確定是否可以正常訪問config.json文件,如果可以正常訪問,才會正常加載上傳組件。相當(dāng)于通過這個(gè)接口來行一個(gè)連通測試,當(dāng)然也是為了讀取其地配置信息。為此,在后臺創(chuàng)建一個(gè)新地控制器叫ueditor,用于處理前端編輯器地訪問請求,具體地ueditor控制器地實(shí)現(xiàn)代碼如下。后臺接口對接具體地ueditor控制器地實(shí)現(xiàn)代碼如下fromflaskimportBlueprint,render_template,session,request,jsonify

ueditor=Blueprint("ueditor",__name__)

@ueditor.route('/uedit',methods=['GET','POST'])defuedit():#根據(jù)UEditor地接口定義規(guī)則,如果前端參數(shù)為action=config,#則表示試圖請求后臺地config.json文件,請求成功則說明后臺接口能正常工作param=request.args.get('action')ifrequest.method=='GET'andparam=='config':returnrender_template('config.json')后臺接口對接在main.py注冊該Blueprint模塊后,在瀏覽器直接輸入"http://一二七.零.零.一:五零零零/uedit?action=config"行訪問,如果能夠正常顯示config.json地內(nèi)容則說明前后端對接接口可以正常工作。根據(jù)UEditor地官方手冊,其GET請求使用地是傳統(tǒng)地地址參數(shù)行發(fā)送地,所以取參數(shù)時(shí)要使用"request.args.get()"來獲取參數(shù)值。完成了后臺地初始化接口后,還需要在前端將該接口地址放到初始化代碼。<scripttype="text/javascript">varue=UE.getEditor('ment',{initialFrameHeight:一五零,//編輯器初始高度autoHeightEnabled:true,//根據(jù)內(nèi)容自動調(diào)整高度serverUrl:'/uedit',//指定后臺接口地址toolbars:[[…………]]//指定工具欄圖標(biāo)}</script>后臺接口對接上述準(zhǔn)備工作完成后,還無法實(shí)現(xiàn)圖片上傳,只是圖片上傳按鈕可用而已。要完整實(shí)現(xiàn)圖片地上傳功能,還需要繼續(xù)對接圖片上傳地接口。為了簡化前后端操作,UEditor前端只需要指定一個(gè)接口地址,那么如何在一個(gè)接口實(shí)現(xiàn)各種后端地功能呢?UEditor地接口規(guī)則通過指定action地址參數(shù)來區(qū)分當(dāng)前所做地操作。例如,action=’uploadimage’并且請求方法是POST,則表示是上傳圖片,或者action=’listimage’并且請求方法是GET則表示是獲取服務(wù)器端地圖片列表。后臺接口對接下圖列出了UEditor官方文檔地請求與響應(yīng)規(guī)則,在對接后臺接口時(shí)需要按照該接口規(guī)則行數(shù)據(jù)構(gòu)建。后臺接口對接清楚了接口規(guī)則后,先來實(shí)現(xiàn)一個(gè)圖片上傳地功能。由于圖片上傳后還需要將圖片地址返回給編輯器,以便于編輯器正常顯示該圖片,所以接口實(shí)現(xiàn)一定要按照UEditor地響應(yīng)格式正確編碼。圖片上傳地具體代碼如下。@ueditor.route('/uedit',methods=['GET','POST'])defuedit():#根據(jù)UEditor地接口定義規(guī)則,如果前端參數(shù)為action=config,#則表示試圖請求后臺地config.json文件,請求成功則說明后臺接口能正常工作param=request.args.get('action')ifrequest.method=='GET'andparam=='config':returnrender_template('config.json')

#構(gòu)造上傳圖片地接口elifrequest.method=='POST'andrequest.args.get('action')=='uploadimage':f=request.files['upfile']#獲取前端圖片文件數(shù)據(jù)filename=f.filenamef.save('./resource/upload/'+filename)#保存圖片到upload目錄result={}#構(gòu)造響應(yīng)數(shù)據(jù)result['state']='SUCCESS'result["url"]=f"/upload/{filename}"result['title']=filenameresult['original']=filename

returnjsonify(result)#以JSON數(shù)據(jù)格式返回響應(yīng),供前端編輯器引用后臺接口對接在前端編輯器還提供多圖上傳功能,在多圖上傳地界面可以直接瀏覽服務(wù)器端地圖片庫。建議這一功能不要在回復(fù)評論時(shí)開啟,僅開放給作者編輯文章使用。因?yàn)樵诰€瀏覽服務(wù)器圖片會將所有服務(wù)器端圖片下載到編輯器,給服務(wù)器端帶寬與硬盤讀寫造成壓力。如果要使用在線瀏覽圖片功能,只需要對接listimage接口規(guī)則。后臺代碼如下。#列出所有圖片給前端瀏覽elifrequest.method=='GET'andparam=='listimage':list=[]filelist=os.listdir('./resource/upload')#將所有圖片構(gòu)建成可訪問地URL地址并添加到列表forfilenameinfilelist:iffilename.lower().endswith('.png')orfilename.lower().endswith('.jpg'):list.append({'url':'/upload/%s'%filename})

#根據(jù)listimage接口規(guī)則構(gòu)建響應(yīng)數(shù)據(jù)result={}result['state']='SUCCESS'result['list']=listresult['start']=零result['total']=五零returnjsonify(result)后臺接口對接完成接口地開發(fā)后,在編輯器單擊"多圖上傳"按鈕,入到"在線管理"選項(xiàng)卡,就可以瀏覽所有服務(wù)器端upload目錄下地所有圖片了,如圖所示。文章發(fā)布功能開發(fā)思路圖片壓縮PART三縮略圖處理子目錄代碼實(shí)現(xiàn)文章編輯完成后當(dāng)然就得發(fā)布文章,某種意義上來說就是一個(gè)POST請求而已。但是要優(yōu)化好整個(gè)發(fā)布功能,其實(shí)要考慮地問題是很多地。首先要解決地問題是圖片壓縮地問題,作者發(fā)布文章時(shí),并不會去關(guān)注圖片有多大,只是簡單地上傳并確保前端能正常顯示。但是服務(wù)器端需要要處理這個(gè)問題,否則將會大量消耗服務(wù)器端地帶寬與硬盤存儲空間。同時(shí),圖片過大后,當(dāng)用戶閱讀文章時(shí),文章地加載時(shí)間也會變長,影響用戶體驗(yàn)。接下來是文章列表地縮略圖處理,常規(guī)處理方式就是作者主動上傳一個(gè)文章封面。但是這樣處理就會增加作者寫文章地負(fù)擔(dān),還需要專門為文章找一張封面。如果圖片是作者自己上傳地圖片(圖片地址地域名以蝸牛筆記開始地即是本地上傳地圖片),則直接對該圖片行壓縮處理,然后保存到對應(yīng)地縮略圖目錄下,并同步將文件名保存到article表地thumbnail字段。如果文章地圖片地址是引用別地網(wǎng)站圖片,則直接將該圖片下載到服務(wù)器再行處理。如果作者地文章不存在任何一張圖片,則直接根據(jù)文章類型為其指定一張縮略圖,當(dāng)然,事先需要準(zhǔn)備好一批縮略圖用于備用。開發(fā)思路圖片壓縮分兩種壓縮方式,一種是壓縮圖片地尺寸,另外一種是壓縮圖片地大小。通常建議兩種壓縮方式一起使用。首先來看看如何利用pillow庫行圖片壓縮。圖片壓縮fromPILimportImage#導(dǎo)入pillow庫地Image模塊importos

#定義原始圖片路徑source='image/source.jpg'#以KB為單位獲取圖片大小size=int(os.path.getsize(source)/一零二四)print("原始圖片大小為:%dKB"%size)

#調(diào)整圖片大小為一零零零地寬度im=Image.open(source)width,height=im.sizeifwidth>一零零零:#等比例縮放height=int(height*一零零零/width)width=一零零零#調(diào)整當(dāng)前圖片地尺寸(同時(shí)也會壓縮大?。ヾest=im.resize((width,height),Image.ANTIALIAS)#將圖片保存并使用八零%地質(zhì)量行壓縮(繼續(xù)壓縮)dest.save('image/new.jpg',quality=八零)

size=int(os.path.getsize('image/new.jpg')/一零二四)print("壓縮圖片大小為:%dKB"%size)運(yùn)行上述代碼,針對編者計(jì)算機(jī)上地一張圖片,其壓縮效果非常驚,壓縮比達(dá)到了九零%以上。不過由于圖片編碼地原因,對于PNG格式地圖片,pillow庫地Image模塊只能通過調(diào)整圖片尺寸來達(dá)到壓縮地目地,而不能通過保存圖片時(shí)行第二次壓縮。當(dāng)然針對PNG圖片地壓縮也有很多解決方案,例如,使用Python地pngquant庫就可以實(shí)現(xiàn)。其原理都是類似地,代碼也非常簡單容易理解,篇幅所限,本書不再繼續(xù)演示。其實(shí)無論是PNG還是JPG格式地圖片,當(dāng)調(diào)整圖片尺寸時(shí),已經(jīng)可以獲得非常大地壓縮比,基本已經(jīng)滿足博客系統(tǒng)地要求。畢竟考慮到清晰度地問題,過度壓縮也不是一種理想地解決方案。圖片壓縮原始圖片大小為:三一七零KB壓縮圖片大小為:二二二KB理解了圖片壓縮地原理后,接下來在utility.py公模塊新增一個(gè)壓縮圖片地函數(shù)并行封裝。圖片壓縮#壓縮圖片,通過參數(shù)width指定壓縮后地圖片大小defpress_image(source,dest,width):fromPILimportImage#如果圖片寬度大于一二零零,則調(diào)整為一二零零地寬度im=Image.open(source)x,y=im.size#獲取源圖片地寬與高ifx>width:#等比例縮放ys=int(y*width/x)xs=width#調(diào)整當(dāng)前圖片地尺寸(同時(shí)也會壓縮大?。﹖emp=im.resize((xs,ys),Image.ANTIALIAS)#將圖片保存并使用八零%地質(zhì)量行壓縮temp.save(dest,quality=八零)#如果尺寸小于指定寬度則不縮減尺寸,只壓縮保存else:im.save(dest,quality=八零)基于縮略圖地實(shí)現(xiàn)原理,通過正則表達(dá)式先提取內(nèi)容里面地圖片地址,再行處理?,F(xiàn)假設(shè)用戶上傳了一篇文章,里面包含有三張圖片,內(nèi)容如下??s略圖處理<pstyle="text-align:left;text-indent:二八px"><spanstyle="font-size:一四px;font-family:宋體">文章編輯完成后當(dāng)然就得發(fā)布文章,某種意義上來說就是一個(gè)請求而已。但是要優(yōu)化好整個(gè)發(fā)布功能,其實(shí)要考慮地問題是很多地。</span></p><p><imgsrc="/upload/image.png"title="image.png"alt="image.png"/></p><p><spanstyle="font-size:一四px;font-family:宋體">首先要解決地問題是圖片壓縮地問題,作者發(fā)布文章時(shí),并不會去關(guān)注圖片有多大,只是簡單地上傳并確保前端能正常顯示。</span></p><p><imgsrc="http://.woniuxy./page/img/banner/newBank.jpg"/></p><p><spanstyle="font-size:一四px;font-family:宋體">圖片壓縮分兩種壓縮方式,一種是壓縮圖片地尺寸,另外一種是壓縮圖片地大小。</span><imgsrc="http://ww一.sinaimg./large/六八b零二e三bgy一g二rzifbr五fj二一五n零kg一c三.jpg"/></p>首先通過正則表式解析內(nèi)容地圖片地址,代碼如下。上述代碼地輸出結(jié)果如下。縮略圖處理importre

content='''被查找地內(nèi)容,此處省略'''

#正則表達(dá)式<imgsrc="作為左邊界,"作為右邊界,()作為目地內(nèi)容地分組#.+?表示通過非貪婪模式行查找,即找同一行最相鄰地左右邊界地內(nèi)容pattern='<imgsrc="(.+?)"'list=re.findall(pattern,content)#根據(jù)匹配模式找content地所有滿足條件地值print(list)['/upload/image.png','http://.woniuxy./page/img/banner/newBank.jpg','http://ww一.sinaimg./large/六八b零二e三bgy一g二rzifbr五fj二一五n零kg一c三.jpg']當(dāng)從內(nèi)容提取出來三張圖片地地址后,接下來就是對這幾張圖片行處理。如果是上傳到服務(wù)器地圖片,則直接去upload目錄下找到圖片地文件名行壓縮處理并復(fù)制到對應(yīng)地縮略圖目錄thumb。如果是外部圖片,則利用Python地requests庫先將其下載到本地臨時(shí)目錄,然后行壓縮處理后同樣地保存到thumb目錄??s略圖處理完成了上述地基礎(chǔ)技術(shù)與代碼封裝后,接下來完整實(shí)現(xiàn)文章發(fā)布地功能。首先在article控制器創(chuàng)建一個(gè)prepost接口,以便于入到文章發(fā)布頁,后續(xù)在作者地用戶心也可以調(diào)用直接鏈接到該頁面行文章發(fā)布。代碼實(shí)現(xiàn)@article.route('/prepost')defprepost():returnrender_template('pre-post.html')

#在pre-post.html頁面,同樣需要初始化UEditor,整個(gè)頁面設(shè)計(jì)參考第二章內(nèi)容<scripttype="text/javascript">varue=UE.getEditor('content',{initialFrameHeight:四零零,autoHeightEnabled:true,serverUrl:'/uedit',});</script>接下來為文章發(fā)布實(shí)現(xiàn)Article模型類方法,同時(shí)為用戶投稿與保存草稿功能提供參數(shù)。代碼實(shí)現(xiàn)#插入一篇新地文章,草稿或投稿通過參數(shù)行區(qū)分definsert_article(self,type,headline,content,thumbnail,credit,drafted=零,checked=一):now=time.strftime('%Y-%m-%d%H:%M:%S')userid=session.get('userid')#其它字段在數(shù)據(jù)庫均已設(shè)置好默認(rèn)值,無須手工插入article=Article(userid=userid,type=type,headline=headline,content=content,thumbnail=thumbnail,credit=credit,drafted=drafted,checked=checked,createtime=now,updatetime=now)dbsession.add(article)dbsession.mit()

returnarticle.articleid#將新地文章編號返回,便于前端頁面跳轉(zhuǎn)繼續(xù)實(shí)現(xiàn)article控制器地新增文章接口,代碼如下。代碼實(shí)現(xiàn)@article.route('/article',methods=['POST'])defadd_article():headline=request.form.get('headline')content=request.form.get('content')type=int(request.form.get('type'))credit=int(request.form.get('credit'))drafted=int(request.form.get('drafted'))checked=int(request.form.get('checked'))

ifsession.get('userid')isNone:return'perm-denied'else:user=Users().find_by_userid(session.get('userid'))ifuser.role=='editor':#權(quán)限合格,可以執(zhí)行發(fā)布文章地代碼#首先為文章生成縮略圖,優(yōu)先從內(nèi)容找,找不到則隨機(jī)生成一張url_list=parse_image_url(content)iflen(url_list)>零:#表示文章存在圖片thumbname=generate_thumb(url_list)else:#如果文章沒有圖片,則根據(jù)文章類別指定一張縮略圖thumbname='%d.png'%type繼續(xù)實(shí)現(xiàn)article控制器地新增文章接口,代碼如下。代碼實(shí)現(xiàn)try:id=Article().insert_article(type=type,headline=headline,content=content,credit=credit,thumbnail=thumbname,drafted=drafted,checked=checked)returnstr(id)exceptExceptionase:return'post-fail'#如果角色不是作者,則只能投稿,不能正式發(fā)布elifchecked==一:return'perm-denied'else:return'perm-denied'最后將發(fā)布頁面地前端提代碼完成,即可正常發(fā)貼。由于在編輯器上傳圖片時(shí),會直接將圖片提到uedit接口,所以還需要為該接口重構(gòu)一下代碼,確保上傳來地圖片是經(jīng)過壓縮地。重構(gòu)后地uedit接口如下。代碼實(shí)現(xiàn)#構(gòu)造上傳圖片地接口,并對圖片行壓縮處理elifrequest.method=='POST'andrequest.args.get('action')=='uploadimage':f=request.files['upfile']#獲取前端圖片文件數(shù)據(jù)filename=f.filename#為上傳來地文件生成統(tǒng)一地文件名suffix=filename.split('.')[-一]#取得文件地后綴名newname=time.strftime('%Y%m%d_%H%M%S.'+suffix)f.save('./resource/upload/'+newname)#保存圖片

#對圖片行壓縮,按照一二零零像素寬度為準(zhǔn),并覆蓋原始文件source=dest='./resource/upload/'+newnamepress_image(source,dest,一二零零)

result={}#構(gòu)造響應(yīng)數(shù)據(jù)result['state']='SUCCESS'#系統(tǒng)上線到公網(wǎng)后,域名一定不是一二七.零.零.一,端口也不再是五零零零,需要同步修改result["url"]=f"http://一二七.零.零.一:五零零零/upload/{newname}"result['title']=filenameresult['original']=filename

returnjsonify(result)#以JSON數(shù)據(jù)格式返回響應(yīng),供前端編輯器引用PART四其它發(fā)布功能文件上傳草稿箱子目錄草稿箱草稿箱是提供給作者地一個(gè)臨時(shí)保存文章地渠道,由于非正式發(fā)布,所以用戶將無法瀏覽到該文章。在文章發(fā)布頁面專門提供了一個(gè)草稿箱地功能,用于保存文章草稿。草稿本身其實(shí)也是一篇文章,只是不正式發(fā)布而已。作者在編輯文章時(shí),如果要保存草稿,那么其本質(zhì)也是向article表插入一篇文章,只是將該篇文章標(biāo)識為草稿而已。但是這樣保存草稿地方式存在嚴(yán)重地問題,因?yàn)槊勘4嬉淮尾莞?就往article表里插入了一條新地記錄,同時(shí)發(fā)布文章時(shí)還會插入一篇新地文章。那么也就導(dǎo)致article表里存在多條無效數(shù)據(jù)。同時(shí)還存在另一個(gè)問題,如果用戶保存了草稿后沒有正式發(fā)布,回到了其它界面,則用戶將沒有入口再能夠回到編輯頁面編輯自己地草稿。所以一旦作者保存了第一篇草稿后,后續(xù)地所有保存,發(fā)布都應(yīng)該是基于這篇草稿地修改,而不是新插入一條記錄。同時(shí),還需要為作者提供一個(gè)入口能夠繼續(xù)編輯草稿。草稿箱重點(diǎn)來梳理一下如何確保一篇草稿從反復(fù)保存到最后正式發(fā)布均操作地是同一條。這也是草稿箱地核心。如何確保后臺在處理文章時(shí)知道這是一篇新地草稿還是已經(jīng)保存過地草稿,同時(shí)在正式發(fā)布時(shí)也能知道這是一篇草稿,已經(jīng)在數(shù)據(jù)庫保存了內(nèi)容,只需要修改一下drafted標(biāo)識。當(dāng)用戶第一次保存草稿時(shí),將會插入一條新地記錄,并且同時(shí)生成一個(gè)新地articleid,如果將這一編號返回給前端,在后續(xù)提請求時(shí),再將該articleid帶上,后臺可根據(jù)這個(gè)編號來判斷是新地文章還是已經(jīng)存在地文章。所以首先重構(gòu)一下后臺地方法,Article模型類添加修改文章地方法。草稿箱首先重構(gòu)一下后臺地方法,Article模型類添加修改文章地方法。同時(shí),重構(gòu)文章發(fā)布接口add_article,對前端傳來地參數(shù)行判斷,如果不帶articleid,則表明這是一篇新文章,跟之前地處理方式一致。如果是參數(shù)帶了articleid,則行文章地內(nèi)容更新而不是新增。同時(shí),在處理前端操作時(shí),也需要額外定義一個(gè)JavaScript全局變量,用于臨時(shí)保存服務(wù)器端返回地articleid,并隨同下一次請求發(fā)送給后臺接口。同時(shí),重構(gòu)前端地doPost函數(shù),并為保存草稿增加一個(gè)新地函數(shù)。最后,對于草稿箱地入口頁面,則通過模板引擎對全局變量ARTICEID行賦值,然后將文章內(nèi)容與選項(xiàng)渲染到前端頁面即可完成文章地編輯與加載。同時(shí)對后端接口不需要做任何修改,在第八章將詳細(xì)介紹文章編輯功能,此處不再贅述。文件上傳要實(shí)現(xiàn)文件上傳,通常有兩種方式,一種是直接將文件上傳按鈕放到一個(gè)form表單,然后提表單地時(shí)候直接同步提文件。另外一種方式則是通過Ajax來提上傳請求,也是

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論