2017年4月3日 星期一

C槽塞爆了怎麼辦?!

如果D槽還有空間就把那些照片、音樂、影片、文件移到D槽吧.如果D槽已經滿了或根本沒有D槽,那只好清一下不要的檔案(大概要用掉一整天的時間)或去買個外接硬碟(花錢解決-而且不貴)。

不過慢著!不要笨笨的在D槽開一個目錄然後把資料通通塞過去。在Windows 10你的大部分檔案都是放在C槽的「使用者」(Users)目錄下,如果把資料通通移到D槽下次打開「相片」、「我的文件」目錄就什麼都沒了,這怎麼行!(是行啦,不過這樣就寫不下去了)

只要跟Windows 10說聲從此以後我漂亮的自拍跟其他沒那麼漂亮的檔案通通都進到D槽,這樣之後依然可以打開「相片」、「我的文件」看到所有的檔案,而且這些檔案都存在D槽了。C槽終於可以空出來囉!接下來就可以繼續拼命灌程式跟拼命放自己的美圖(至少一陣子啦,直到硬碟爆掉為止)。

只要三個步驟:
  1. 開啟設定
  2. 選「儲存空間」
  3. 改儲存位置

2015年12月27日 星期日

The Flask Mega-Tutorial, Part II 導讀

之前為了讓台灣的朋友能夠較快上手,寫了 The Flask Mega-Tutorial, Part I解說加上 Windows 環境設定。似乎對一些人還蠻有用,所以這裡繼續寫了 Part II 。這並不是要直接翻譯 Miguel Grinberg 寫的 The Flask Mega-Tutorial ,主要是為了導讀。請務必閱讀原文。好啦,你們只想看中文,不過真的,讀讀看!他寫的簡單易懂。
我們來看看 The Flask Mega-Tutoral Part II: Templates 說了什麼。Template 是套版的意思,那套版是什麼呢?我們慢慢看下去。
這個教學系列最後會完成一個微博網站。作者命名他為 microblog ,也就是微博的意思。
開始之前請確定已經有 Part I 練習的完成品。執行 flask/Scripts/python run.py 後,可以從瀏覽器打開 http://localhost:500 看到到 Hello, World! 的字樣。

要解決的問題

我們讓這小程式熱鬧、好看一點。所以畫面上加的大標題,然後跟使用者打個招呼。但是目前為止還沒有登入的機制,所以使用者就先直接寫死 Minguel (原文作者的名),當然因為只是臨時寫死的東西,所以這使用者要叫什麼都可以。因為要加大標題就要動到畫面的排版,所以只是回傳沒有格式的文字不夠用了,我們把 app/views.py 內容改成 HTML 。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
from app import app

@app.route('/')
@app.route('/index')
def index():
	user = { 'nickname': 'Miguel' } # fake user
	return '''
<html>
	<head>
		<title>Home Page</title>
	</head>
	<body>
		<h1>Hello, ''' + user['nickname'] + '''</h1>
	</body>
</html>
'''
程式改好後,可以再跑一次 run.py ,瀏覽器中應該要可以看到大大的 Hello, Miguel ,頁籤的標題也顯示了 Home Page 。
程式中的 user 變數是以大括號建立的 dictionary 物件,因為沒有登入的機制,給的資料只是隨便的假資料,也就是所謂的假物件( mock object )。回傳內容用了三個單引號包著可以直接寫出多行的內容建立含有換行資訊的字串。
如果你還沒發現的話,直接把網頁內容寫到程式中回傳是個很糟的做法。
當畫面開始豐富一點時,程式很快的會變得非常複雜。如果每個畫面的程式都是各自回傳寫好的網頁內容,想要修改整個網站排版時就得一個一個程式修改。這種做法在網站越來越大時完全會行不通。

用套版來處理

如果我們把程式的處理邏輯跟網頁呈現方式分開來的話,就會乾淨很多。你還可以去找個網頁設計師幫你寫超棒的網頁畫面,你來負責寫背後的 Python 程式就好。 (依照過往的經驗,網頁設計師寫出來的網頁畫面最好還是重做,不過目前為止應該可以感受到把邏輯跟畫面分開的好處吧!)套版就是可以把這邏輯跟畫面分開的工具。
那就來寫第一個套版吧,寫在 app/templates/index.html :
1
2
3
4
5
6
7
8
<html>
	<head>
		<title>{{ title }} - microblog</title>
	</head>
	<body>
		<h1>Hello, {{ user.nickname }}!</h1>
	</body>
</html>
這看起來會很像一般的 HTML 網頁,不過有幾個地方用 {{ ... }} 加了保留區給動態的內容用。
接下來看如何在 app/views.py 中用這個套版,記得要在第一行加 from flask import render_template :
1
2
3
4
5
6
7
8
from flask import render_template
from app import app

@app.route('/')
@app.route('/index')
def index():
	user = { 'nickname': 'Miguel' } # fake user
	return render_template('index.html', title='Home', user=user)
再執行一次程式,可以在瀏覽器看到跟改成套版之前一樣的畫面,用瀏覽器檢視原始碼功能看看是不是跟我們的套版一樣。
render_template 可以把指定的套版檔案套入傳入的參數。背後使用 Jinja2 套版引擎。 Jinja2 以同名參數的內容將套版中的 {{ ... }} 取代。

套版中的控制語句

Jinja2 也可以把控制語句用在套版中的 {% ... %} 區塊,我們把 if 加到套版中看看, app/templates/index.html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<html>
	<head>
		{% if title %}
		<title>{{ title }} - microblog</title>
		{% else %}
		<title>Welcome to microblog</title>
		{% endif %}
	</head>
	<body>
		<h1>Hello, {{ user.nickname }}!</h1>
	</body>
</html>
這個套版現在變的聰明一點了,他可以在沒有提供標題時自己寫出一個預設的標題Welcome to microblog。可以在 render_template 中不傳入 title 參數看看會有什麼樣的結果。

套版中的迴圈

登入的會員很有可能想看他在追蹤的人的貼文。我們來看看怎麼做。
我們還沒有登入的機制,方便起見,我們先在 views.py 做些假會員資料。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
def index():
	user = { 'nickname': 'Miguel' } # fake user
	posts = [ # 假的貼文陣列
		{
			'author': {'nickname': 'John'},
			'body': 'Beautiful day in Portland!'
		},
		{
			'author': {'nickname': 'Susan'},
			'body': 'The Avengers movie was so cool!'
		}
	]
	return render_template('index.html', title='Home', user=user, posts=posts)
我們用一個 list 來存放所有的貼文。每個貼文中含 author 跟 body 欄位(如果英文真的那麼差的話,那兩欄分別代表作者跟貼文內容,nickname 是作者的暱稱)。之後用真的資料庫來存放這些貼文時我們會持續用相同的欄位名稱。這樣就不用回頭改套版中的欄位名稱了。
一個 list 中可以放不定數量的貼文,套版要忠實的把每一筆輸出在結果畫面中。如果要限制顯示的貼文數量,那應該要讓 views.py 中的程式決定 list 中要有幾筆貼文。決定顯示幾筆不是套版的工作。
我們在 app/templates/index.html 加一個 for 迴圈輸出貼文:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<html>
	<head>
		{% if title %}
		<title>{{ title }} - microblog</title>
		{% else %}
		<title>Welcome to microblog</title>
		{% endif %}
	</head>
	<body>
		<h1>Hello, {{ user.nickname }}!</h1>
		{% for post in posts %}
		<div><p>{{ post.author.nickname }} says: <b>{{ post.body }}</b></p></div>
		{% endfor %}
	</body>
</html>
這樣就可以了,再到瀏覽器看看新的畫面。

套版繼承

接下來最後的討論項目。
這個 microblog 網站的網頁的最上方要有一塊導覽列。裡面會包含編輯個人資訊、登入、登出等連結。我們可以直接把導覽列寫到 index.html 中,不過網站越大時網頁也跟著變多,如果每次要改導覽頁時都要從 index.html 複製過去會很麻煩。萬一複製後又要改導覽列,那就得花很多時間改了。
還有 Jinja2 的套版繼承功能,他可以讓我們把所有套版相同的部分都拉出來放到一個共用的套版中,然後再讓所有的套版繼承這個共用的套版。
我們就來新增這個共用的套版,放在 app/templates/base.html ,把導覽列跟一些之前寫好的套版內容寫在裡面:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<html>
	<head>
		{% if title %}
		<title>{{ title }} - microblog</title>
		{% else %}
		<title>Welcome to microblog</title>
		{% endif %}
	</head>
	<body>
		<div>Microblog: <a href="/index">Home</a></div>
		<hr>
		{% block content %}{% endblock %}
	</body>
</html>
這個套版裡用到的 block 控制語句被指定了一個名稱,讓繼承他的套版插入專屬的內容。接下來我們把 index.html 改成繼承 base.html 。
1
2
3
4
5
6
7
{% extends "base.html" %}
{% block content %}
	<h1>Hi, {{ user.nickname }}!</h1>
	{% for post in posts %}
	<div><p>{{ post.author.nickname }} says: <b>{{ post.body }}</b></p></div>
	{% endfor %}
{% endblock %}
因為 base.html 已經定義了整體畫面架構,我們可以只留內容的部分。 extends 告訴 Jinja2 他繼承了 base.html ,產生 index.html 得畫面時要先引入 base.html 。因為兩個套版都有叫做 content 的 block ,所以 Jinja2 知道要把同名的內容塞到共用套版的哪個位置。之後新寫的套版都會先繼承 base.html。
套版就講到這了,不要忘了看原文喔。

2015年10月10日 星期六

The Flask Mega-Tutorial, Part I Windows 環境設定

這邊整理了 The Flask Mega-Tutorial, Part I: Hello World! 在 Windows 上執行的指令。這整理的用意是原文中會各別提到在 Linux 跟 OS X 中的指令,對於不熟那些系統的人來說讀起來會有點困擾。

這篇並非對原文的直接翻譯,想要練習的人請務必閱讀原文。

在開始之前,請先安裝 Python ,這篇是專門為 Python 版本 3.4 以上說明。如果 3.4 以下的版本請另外安裝 pip 跟 virtualenv (就是請自己想辦法的意思)。

安裝 Python 時請記得將 Python 安裝的位置加到環境變數的路徑中,如安裝 3.5 時,要記得把 Add Python 3.5 to PATH 勾起來。
安裝Python時勾選Add Python to PATH

那就開始,打開「命令提示字元」,他在「附屬應用程式下面」。台灣微軟可以把命令提示字元改成比較有意義的名稱嗎?譬如指令行或終端機。他實在沒有在提示任何東西... 或字元。

首先要先有一個程式開發專屬的目錄夾,這目錄的目的在方便跟其他平常的檔案分開來(如那些無聊的 word 檔或小孩的照片),不然沒有其他任何意義。個人習慣叫做 projects ,不過要叫什麼名字都可以。可以從檔案總管新增這個目錄,或拿以下指令新增:
md projects
不要忘記用以下指令移到你的專屬目錄下:
cd projects
新增專案目錄
md microblog
執行中目錄移到專案目錄下
cd microblog
開始建置 Flask 環境。為什麼要建立 Flask 環境?因為建立出獨立的環境才不會影響系統中其它 Python 程式。如果還是不懂為什麼這麼做,沒關係,改天再去搞懂。真的,改天請真的去搞懂。
python -m venv flask
接下來要在安裝一堆將來會用到的程式庫,現在還不懂沒關係:
flask\Scripts\pip install flask
flask\Scripts\pip install flask-login
flask\Scripts\pip install flask-openid
flask\Scripts\pip install flask-mail
flask\Scripts\pip install flask-sqlalchemy
flask\Scripts\pip install sqlalchemy-migrate
flask\Scripts\pip install flask-whooshalchemy
flask\Scripts\pip install flask-wtf
flask\Scripts\pip install flask-babel
flask\Scripts\pip install guess_language
flask\Scripts\pip install flipflop
flask\Scripts\pip install coverage
整體架構環境快好了,再建立幾個目錄:
md app
md app\static
md app\templates
md tmp
app 目錄會放實際網站程式。

YES! 可以開始寫程式了,如果現在還沒有你最愛的文字編輯器,或心中想說文字編輯器是小三的話,可以安裝 notepad++ 來寫。注意程式中的縮排一定要用 tab ,如 views.py 中的 return "Hello, World!" 就要用 tab 縮排。

在這一次的練習總共有三個程式檔。

第一個程式檔

在剛剛建立的  app 目錄下編輯一個新的檔案: __init__.py ,所以這檔案路徑會是
app\__init__.py
程式內容不算空白行的話就下面這三行而以:
from flask import Flask

app = Flask(__name__)
from app import views
在 Python 中 __init__.py 檔案,只要是同一個目錄(同package)的任一程式檔(模組)被呼叫到,就會先執行 __init__.py 中的程式,不過只會執行一次。如果同 package 中有兩個程式檔分別被呼叫到,只有第一個檔被呼叫時會執行 __init__.py 。

第二個程式檔

一樣在 app 目錄下新增檔案 views.py ,檔案路徑是
app\views.py
程式內容如下,注意縮排要用 tab :
from app import app

@app.route('/')
@app.route('/index')
def index():
    return "Hello, World!"

第三個程式檔

這個檔案就直接在 microblog 目錄下了,叫做 run.py
#!flask/bin/python
from app import app
app.run(debug=True)

完成

第一個 Flask 網站程式寫好了。恩,就這樣而已。只要在把他跑起來就好了。說到要跑... 就是 run 了。run.py 其實不算網站程式的一部分,他只是叫我們的網站程式( app )啟動。請按照以下指令執行,刻意使用 flask\Scripts 中的 python 這樣才能把程式在剛剛建立起來的獨立環境中跑。
flask\Scripts\python run.py
最後享受程式的成果,把你最喜歡的網路瀏覽器打開,網址輸入
http://localhost:5000
或以下網址也會有一模一樣的結果:
http://localhost:5000/index