Python学习笔记:Day11 编写日志创建页
前言
最近在學(xué)習(xí)深度學(xué)習(xí),已經(jīng)跑出了幾個(gè)模型,但Pyhton的基礎(chǔ)不夠扎實(shí),因此,開(kāi)始補(bǔ)習(xí)Python了,大家都推薦廖雪峰的課程,因此,開(kāi)始了學(xué)習(xí),但光學(xué)有沒(méi)有用,還要和大家討論一下,因此,寫(xiě)下這些帖子,廖雪峰的課程連接在這里:廖雪峰
Python的相關(guān)介紹,以及它的歷史故事和運(yùn)行機(jī)制,可以參見(jiàn)這篇:python介紹
Python的安裝可以參見(jiàn)這篇:Python安裝
Python的運(yùn)行模式以及輸入輸出可以參見(jiàn)這篇:Python IO
Python的基礎(chǔ)概念介紹,可以參見(jiàn)這篇:Python 基礎(chǔ)
Python字符串和編碼的介紹,可以參見(jiàn)這篇:Python字符串與編碼
Python基本數(shù)據(jù)結(jié)構(gòu):list和tuple介紹,可以參見(jiàn)這篇:Python list和tuple
Python控制語(yǔ)句介紹:ifelse,可以參見(jiàn)這篇:Python 條件判斷
Python控制語(yǔ)句介紹:循環(huán)實(shí)現(xiàn),可以參見(jiàn)這篇:Python循環(huán)語(yǔ)句
Python數(shù)據(jù)結(jié)構(gòu):dict和set介紹Python數(shù)據(jù)結(jié)構(gòu)dict和set
Python函數(shù)相關(guān):Python函數(shù)
Python高階特性:Python高級(jí)特性
Python高階函數(shù):Python高階函數(shù)
Python匿名函數(shù):Python匿名函數(shù)
Python裝飾器:Python裝飾器
Python偏函數(shù):Python偏函數(shù)
Python模塊:Python模塊
Python面向?qū)ο缶幊?#xff08;1):Python面向?qū)ο?
Python面向?qū)ο缶幊?#xff08;2):Python面向?qū)ο?#xff08;2)
Python面向?qū)ο缶幊?#xff08;3):Python面向?qū)ο?#xff08;3)
Python面向?qū)ο缶幊?#xff08;4):Pyhton面向?qū)ο?#xff08;4)
Python面向?qū)ο蟾呒?jí)編程(上):Python面向?qū)ο蟾呒?jí)編程(上)
Python面向?qū)ο蟾呒?jí)編程(中上):Python面向?qū)ο蟾呒?jí)編程(中上)
Python面向?qū)ο蟾呒?jí)編程(中下):Python面向?qū)ο蟾呒?jí)編程(中下)
Python面向?qū)ο蟾呒?jí)編程(完):Python面向?qū)ο蟾呒?jí)編程(完)
Python錯(cuò)誤調(diào)試(起):Python調(diào)試:起
Python錯(cuò)誤調(diào)試(承):Python調(diào)試:承
Python錯(cuò)誤調(diào)試(轉(zhuǎn)):Python調(diào)試:轉(zhuǎn)
Python錯(cuò)誤調(diào)試(合):python調(diào)試:合
Python文件IO編程:Python文件IO
Python文件IO編程2:Python文件IO2
Python文件IO編程3:PYthon文件IO3
Python進(jìn)程和線程(起):Python進(jìn)程和線程起
Python進(jìn)程和線程(承):Python進(jìn)程和線程承
Python進(jìn)程和線程(轉(zhuǎn)):Python進(jìn)程和線程轉(zhuǎn)
Python進(jìn)程和線程(合):Python進(jìn)程和線程合
Python正則表達(dá)式:Python正則表達(dá)式
Python學(xué)習(xí)筆記:常用內(nèi)建模塊1:Python學(xué)習(xí)筆記:常用內(nèi)建模塊1
Python學(xué)習(xí)筆記:常用內(nèi)建模塊2:Python學(xué)習(xí)筆記:常用內(nèi)建模塊2
Python學(xué)習(xí)筆記:常用內(nèi)建模塊3:Python學(xué)習(xí)筆記:常用內(nèi)建模塊3
Python學(xué)習(xí)筆記:常用內(nèi)建模塊4:Python學(xué)習(xí)筆記: 常用內(nèi)建模塊4
Python學(xué)習(xí)筆記:常用內(nèi)建模塊5:Python學(xué)習(xí)筆記: 常用內(nèi)建模塊5
Python學(xué)習(xí)筆記:常用內(nèi)建模塊6:Python學(xué)習(xí)筆記:常用內(nèi)建模塊6
Python學(xué)習(xí)筆記:第三方模塊1:Python常用第三方模塊
Python學(xué)習(xí)筆記:第三方模塊2:Python常用第三方模塊
Python學(xué)習(xí)筆記:第三方模塊3:Python常用第三方模塊
Pytho學(xué)習(xí)筆記:網(wǎng)絡(luò)編程:Python網(wǎng)絡(luò)編程
Python學(xué)習(xí)筆記:電子郵件:Python電子郵件1
Python學(xué)習(xí)筆記:SMTP服務(wù)器:PythonSMTP服務(wù)器
Python學(xué)習(xí)筆記:POP3服務(wù)器:PythonPOP3服務(wù)器
Python學(xué)習(xí)筆記:Python數(shù)據(jù)庫(kù) Python數(shù)據(jù)庫(kù)1
Python學(xué)習(xí)筆記:Python數(shù)據(jù)庫(kù)2Python數(shù)據(jù)庫(kù)2
Python學(xué)習(xí)筆記:web開(kāi)發(fā)1Python學(xué)習(xí)筆記:web開(kāi)發(fā)1
Python學(xué)習(xí)筆記:web開(kāi)發(fā)2Python學(xué)習(xí)筆記: web開(kāi)發(fā)2
Python學(xué)習(xí)筆記: web開(kāi)發(fā)3Python學(xué)習(xí)筆記: web開(kāi)發(fā)3
Python學(xué)習(xí)筆記:異步IO(1)Python學(xué)習(xí)筆記:異步IO(1)
Python學(xué)習(xí)筆記:異步IO(2)Python學(xué)習(xí)筆記:異步IO(2)
Python學(xué)習(xí)筆記:異步IO(3)Python學(xué)習(xí)筆記:異步IO(3)
Python學(xué)習(xí)筆記:Day 1-2開(kāi)發(fā)Python學(xué)習(xí)筆記:Day1-2開(kāi)發(fā)
Python學(xué)習(xí)筆記:Day 3 ORMPython學(xué)習(xí)筆記:Day3 ORM
Python學(xué)習(xí)筆記:Day 4 ModelPython學(xué)習(xí)筆記:Day4Model
Python學(xué)習(xí)筆記:Day 5 web框架PYTHON學(xué)習(xí)筆記:DAy5
Python學(xué)習(xí)筆記:Day 6 配置文件Python學(xué)習(xí)筆記:Day 6 配置文件
Python學(xué)習(xí)筆記:Day 7 編寫(xiě)MVCPython學(xué)習(xí)筆記:Day 7編寫(xiě)MVC
Python學(xué)習(xí)筆記:Day 8 構(gòu)建前端Python學(xué)習(xí)筆記:Day 8 構(gòu)建前端
Python學(xué)習(xí)筆記:Day 9 編寫(xiě)APIPython 9編寫(xiě)API
Python學(xué)習(xí)筆記:Day 10 用戶注冊(cè)和登陸Python 10用戶注冊(cè)和登陸
目錄
- 前言
- 目錄
- 編寫(xiě)日志創(chuàng)建頁(yè)
編寫(xiě)日志創(chuàng)建頁(yè)
在Web開(kāi)發(fā)中,后端代碼寫(xiě)起來(lái)其實(shí)是相當(dāng)容易的。
例如,我們編寫(xiě)一個(gè)REST API,用于創(chuàng)建一個(gè)Blog:
@post('/api/blogs') def api_create_blog(request, *, name, summary, content):check_admin(request)if not name or not name.strip():raise APIValueError('name', 'name cannot be empty.')if not summary or not summary.strip():raise APIValueError('summary', 'summary cannot be empty.')if not content or not content.strip():raise APIValueError('content', 'content cannot be empty.')blog = Blog(user_id=request.__user__.id, user_name=request.__user__.name, user_image=request.__user__.image, name=name.strip(), summary=summary.strip(), content=content.strip())yield from blog.save()return blog編寫(xiě)后端Python代碼不但很簡(jiǎn)單,而且非常容易測(cè)試,上面的API:api_create_blog()本身只是一個(gè)普通函數(shù)。
Web開(kāi)發(fā)真正困難的地方在于編寫(xiě)前端頁(yè)面。前端頁(yè)面需要混合HTML、CSS和JavaScript,如果對(duì)這三者沒(méi)有深入地掌握,編寫(xiě)的前端頁(yè)面將很快難以維護(hù)。
更大的問(wèn)題在于,前端頁(yè)面通常是動(dòng)態(tài)頁(yè)面,也就是說(shuō),前端頁(yè)面往往是由后端代碼生成的。
生成前端頁(yè)面最早的方式是拼接字符串:
s = '<html><head><title>'+ title+ '</title></head><body>'+ body+ '</body></html>'顯然這種方式完全不具備可維護(hù)性。所以有第二種模板方式:
<html> <head><title>{{ title }}</title> </head> <body>{{ body }} </body> </html>ASP、JSP、PHP等都是用這種模板方式生成前端頁(yè)面。
如果在頁(yè)面上大量使用JavaScript(事實(shí)上大部分頁(yè)面都會(huì)),模板方式仍然會(huì)導(dǎo)致JavaScript代碼與后端代碼綁得非常緊密,以至于難以維護(hù)。其根本原因在于負(fù)責(zé)顯示的HTML DOM模型與負(fù)責(zé)數(shù)據(jù)和交互的JavaScript代碼沒(méi)有分割清楚。
要編寫(xiě)可維護(hù)的前端代碼絕非易事。和后端結(jié)合的MVC模式已經(jīng)無(wú)法滿足復(fù)雜頁(yè)面邏輯的需要了,所以,新的MVVM:Model View ViewModel模式應(yīng)運(yùn)而生。
MVVM最早由微軟提出來(lái),它借鑒了桌面應(yīng)用程序的MVC思想,在前端頁(yè)面中,把Model用純JavaScript對(duì)象表示:
<script>var blog = {name: 'hello',summary: 'this is summary',content: 'this is content...'}; </script>View是純HTML:<form action="/api/blogs" method="post"><input name="name"><input name="summary"><textarea name="content"></textarea><button type="submit">OK</button> </form>由于Model表示數(shù)據(jù),View負(fù)責(zé)顯示,兩者做到了最大限度的分離。
把Model和View關(guān)聯(lián)起來(lái)的就是ViewModel。ViewModel負(fù)責(zé)把Model的數(shù)據(jù)同步到View顯示出來(lái),還負(fù)責(zé)把View的修改同步回Model。
ViewModel如何編寫(xiě)?需要用JavaScript編寫(xiě)一個(gè)通用的ViewModel,這樣,就可以復(fù)用整個(gè)MVVM模型了。
好消息是已有許多成熟的MVVM框架,例如AngularJS,KnockoutJS等。我們選擇Vue這個(gè)簡(jiǎn)單易用的MVVM框架來(lái)實(shí)現(xiàn)創(chuàng)建Blog的頁(yè)面templates/manage_blog_edit.html:
{% extends '__base__.html' %}{% block title %}編輯日志{% endblock %}{% block beforehead %}<script> varID = '{{ id }}',action = '{{ action }}'; function initVM(blog) {var vm = new Vue({el: '#vm',data: blog,methods: {submit: function (event) {event.preventDefault();var $form = $('#vm').find('form');$form.postJSON(action, this.$data, function (err, r) {if (err) {$form.showFormError(err);}else {return location.assign('/api/blogs/' + r.id);}});}}});$('#vm').show(); } $(function () {if (ID) {getJSON('/api/blogs/' + ID, function (err, blog) {if (err) {return fatal(err);}$('#loading').hide();initVM(blog);});}else {$('#loading').hide();initVM({name: '',summary: '',content: ''});} }); </script>{% endblock %}{% block content %}<div class="uk-width-1-1 uk-margin-bottom"><div class="uk-panel uk-panel-box"><ul class="uk-breadcrumb"><li><a href="/manage/comments">評(píng)論</a></li><li><a href="/manage/blogs">日志</a></li><li><a href="/manage/users">用戶</a></li></ul></div></div><div id="error" class="uk-width-1-1"></div><div id="loading" class="uk-width-1-1 uk-text-center"><span><i class="uk-icon-spinner uk-icon-medium uk-icon-spin"></i> 正在加載...</span></div><div id="vm" class="uk-width-2-3"><form v-on="submit: submit" class="uk-form uk-form-stacked"><div class="uk-alert uk-alert-danger uk-hidden"></div><div class="uk-form-row"><label class="uk-form-label">標(biāo)題:</label><div class="uk-form-controls"><input v-model="name" name="name" type="text" placeholder="標(biāo)題" class="uk-width-1-1"></div></div><div class="uk-form-row"><label class="uk-form-label">摘要:</label><div class="uk-form-controls"><textarea v-model="summary" rows="4" name="summary" placeholder="摘要" class="uk-width-1-1" style="resize:none;"></textarea></div></div><div class="uk-form-row"><label class="uk-form-label">內(nèi)容:</label><div class="uk-form-controls"><textarea v-model="content" rows="16" name="content" placeholder="內(nèi)容" class="uk-width-1-1" style="resize:none;"></textarea></div></div><div class="uk-form-row"><button type="submit" class="uk-button uk-button-primary"><i class="uk-icon-save"></i> 保存</button><a href="/manage/blogs" class="uk-button"><i class="uk-icon-times"></i> 取消</a></div></form></div>{% endblock %}初始化Vue時(shí),我們指定3個(gè)參數(shù):
el:根據(jù)選擇器查找綁定的View,這里是#vm,就是id為vm的DOM,對(duì)應(yīng)的是一個(gè)
標(biāo)簽;data:JavaScript對(duì)象表示的Model,我們初始化為{ name: ”, summary: ”, content: ”};
methods:View可以觸發(fā)的JavaScript函數(shù),submit就是提交表單時(shí)觸發(fā)的函數(shù)。
接下來(lái),我們?cè)跇?biāo)簽中,用幾個(gè)簡(jiǎn)單的v-model,就可以讓Vue把Model和View關(guān)聯(lián)起來(lái):
Form表單通過(guò)把提交表單的事件關(guān)聯(lián)到submit方法。
需要特別注意的是,在MVVM中,Model和View是雙向綁定的。如果我們?cè)贔orm中修改了文本框的值,可以在Model中立刻拿到新的值。試試在表單中輸入文本,然后在Chrome瀏覽器中打開(kāi)JavaScript控制臺(tái),可以通過(guò)vm.name訪問(wèn)單個(gè)屬性,或者通過(guò)vm.$data訪問(wèn)整個(gè)Model:

ript邏輯中修改了Model,這個(gè)修改會(huì)立刻反映到View上。試試在JavaScript控制臺(tái)輸入vm.name = ‘MVVM簡(jiǎn)介’,可以看到文本框的內(nèi)容自動(dòng)被同步了:
雙向綁定是MVVM框架最大的作用。借助于MVVM,我們把復(fù)雜的顯示邏輯交給框架完成。由于后端編寫(xiě)了獨(dú)立的REST API,所以,前端用AJAX提交表單非常容易,前后端分離得非常徹底。
總結(jié)
以上是生活随笔為你收集整理的Python学习笔记:Day11 编写日志创建页的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 根据经纬度坐标配准_扫描地图投影的识别及
- 下一篇: websocket python爬虫_p