Flask開發博客(上)

本博客采用創作共用版權協議, 要求署名、非商業用途和保持一致. 轉載本博客文章必須也遵循署名-非商業用途-保持一致的創作共用協議.

Flask博客源碼公開在Github

博客歡迎界面
博客主頁

緣起

最近想讀讀python方向的源碼, 想Pythonic一點, 左右看去, 最后決定讀Flask源碼.

既然決定讀源碼, 我認為首先要簡單的了解:

  • 框架的功能
  • 具體接口
  • 實現一個簡單的輪子.

Flask我就不多介紹了, 網上一搜一大把, python幾大著名Web框架之一, 以其輕量級, 高可擴展性而著名.

那么我們開始造輪子之旅吧

環境相關:
Mac OS X 10.10.3
Sublime Text 3
FLask 0.10.1
Python 3.4.1 # 請放手Python2.7.8, 擁抱Python3

下文主要內容:

  • 介紹Flask搭建博客依賴(隨著文章的圓滿, 會逐漸添加)
  • 搭建博客歡迎頁面
  • 搭建博客基本框架

Flask安裝及相關插件

框架及插件:

數據庫:

  • mongo(了解并會使用一種NoSQL會有很大的好處)

環境配置

$ pip install virtualenv
$ virtualenv -p /usr/local/bin/python3.4 Flask
$ source Flask/bin/activate
$ pip install Flask, Flask-Script, Flask-WTF, flask-mongoengine

項目骨架

請根據下面的Tree文件結構建立文件夾和文件

$ tree ./

./
├── README.md
├── app/
│   ├── __init__.py
│   ├── models.py
│   ├── static/
│   ├── templates/
│   └── views.py
├── config.py
├── manage.py
├── requirements.txt
  • app為項目核心源碼
  • static為項目靜態文件
  • templates為項目HTML模板

Hello World

國際慣例, 編程第一步...

$ vim app/__init__.py

# -*- coding: utf-8 -*-
#!/usr/bin/env python

from flask import Flask

app = Flask(__name__)  #創建Flask類的實例
app.config.from_object("config")  #從config.py讀入配置

#這個import語句放在這里, 防止views, models import發生循環import
from app import views, models  

views.py用于便攜Blog的主邏輯, 和Django中views.py功能相同

$ vim app/views.py

# -*- coding: utf-8 -*-
#!/usr/bin/env python

from app import app
from flask import render_template

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

運用Flask-Script為Flask編寫服務器腳本, 產生類似Django的運行方式

$vim manage.py
# -*- coding: utf-8 -*-
#!/usr/bin/env python

from flask.ext.script import Manager, Server
from app import app

manager = Manager(app)
manager.add_command("runserver", 
        Server(host="127.0.0.1", port=5000, use_debugger=True))

if __name__ == '__main__':
    manager.run()

運行服務器

$ python manage.py flask

瀏覽器打開http://127.0.0.1:5000/, 正式踏出第一步...

博客搭建框架

編寫歡迎頁面及樣式

$ vim app/templates/welcome.html

<html>
  <head>
    {% if title %}
    <title>{{ title }} - 雪憶</title>
    {% else %}
    <title>雪憶</title>
    {% endif %}
    <link rel="stylesheet" >
    <link rel="stylesheet" href="{{ url_for('static', filename='welcome.css') }}">
</head>
<body>
<div id="wrapper">
  <div id="info">
    <div id="info-content">
      <h1><strong>Andrew Liu</strong> 雪  憶</h1>
      <p>雪憶, 如雪般單純, 冷靜思考.</p>
    </div>
  </div>
</div><!-- #wrapper -->
</body>
</html>
$ vim app/static/welcome.css

/* reset */
* {
  margin: 0;
  padding: 0;
}

#wrapper {
  position: absolute;
  width: 100%;
  height: 100%;
  overflow: hidden;
}

label {
  cursor: pointer;
}
label:focus {
  outline: none;
}

/* for show */
html, body {
  height: 100%;
}

body {
  background: url(http://37.media.tumblr.com/f6c67ec2821a91051e4175f8a102e1e2/tumblr_n6rzpcsMk41st5lhmo1_1280.jpg) 50% 50%/cover;
}

p {
  margin-bottom: 15px;
}

#info {
  display: table;
  background: rgba(0, 0, 0, 0.4);
  height: 100%;
  width: 100%;
}
#info #info-content {
  display: table-cell;
  vertical-align: middle;
  text-align: center;
  text-transform: uppercase;
  color: #fff;
  font-size: 12px;
}
#info #info-content h1 {
  color: #fff;
  border: 3px solid #fff;
  text-align: center;
  background: rgba(0, 0, 0, 0.1);
  font-size: 22px;
  font-weight: normal;
  padding: 20px;
  margin: 10px;
  display: inline-block;
}
#info #info-content h1 strong {
  display: block;
  font-size: 26px;
}

現在更改views.py

# -*- coding: utf-8 -*-
#!/usr/bin/env python

from app import app
from flask import render_template, url_for

@app.route('/')
def index():
    return render_template('welcome.html', title="Welcome")

到現在為止我們已經完成了歡迎頁面的搭建

編寫博客主頁框架和樣式

$ vim  app/templates/base.html
<html>
  <head>
    {% if title %}
    <title>{{ title }} - 雪憶</title>
    {% else %}
    <title>雪憶</title>
    {% endif %}
    <link rel="stylesheet" >
    <link rel="stylesheet" href="{{ url_for('static', filename='base.css') }}">
</head>
<body>
<header class="header">
  <ul>
    <li class="cor-1"></li>
    <li class="cor-2"></li>
    <li class="cor-3"></li>
    <li class="cor-4"></li>
    <li class="cor-5"></li>
  </ul>
  </header>
<div class="wrap">
  

<nav class="menu">
  <ul>
    <li>
      <a href="#">Home</a>
    </li>
    <li>
      <a href="#">Archive</a>
    </li>
    <li>
      <a href="#">About me</a>
    </li>
  </ul>
  </nav>
    <aside class="sidebar">
      <div class="widget">
      <h2>Michael</h2>
      <p>Hello, my name’s <b>Andrew Liu</b>. I’m 23 years old. I live in <b>NanJing (China)</b>. I am a <b>Pythoner</b>.<br> Contact Me:<br><b>liu.bin.coder@gmail.com</b></p>
      </div>
      <div class="widget">
      <h2>Title</h2>
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
      </div>

  </aside>
    {% block content %}{% endblock %}
</div>
</body>
</html>
$vim app/static/base.css

@import url(http://fonts.googleapis.com/css?family=Open+Sans:400,800,700,600,300);

body {
  margin:0;
  font-family: 'Open Sans', sans-serif;
  background: #eee;
}

hr {
  background:#dedede;
  border:0;
  height:1px;
}

.header {
  overflow: hidden;
  display:block;
  position:fixed;
  top:0;
  margin:0;
  width:100%;
  height:4px;
  text-align:center;
}

.header ul {
  margin:0;
  padding:0;
}

.header ul li {
  overflow:hidden;
  display:block;
  float:left;
  width:20%;
  height:4px;
}

.header .cor-1 {
  background:#f1c40f;
}

.header .cor-2 {
  background:#e67e22;
}

.header .cor-3 {
  background:#e74c3c;
}

.header .cor-4 {
  background:#9b59b6;
}

.header .cor-5 {
  background-color: hsla(10,40%,50%,1);
}

.wrap {
  width: 950px;
  margin:25px auto;
}

nav.menu ul {
  overflow:hidden;
  float:left;
  width: 650px;
  padding:0;
  margin:0 0 0;
  list-style: none;
  color:#fff;
  background: #1abc9c;
    -webkit-box-shadow: 1px 1px 1px 0px rgba(204,204,204,0.55);
  -moz-box-shadow: 1px 1px 1px 0px rgba(204,204,204,0.55);
  box-shadow: 1px 1px 1px 0px rgba(204,204,204,0.55);
}

nav.menu ul li {
  float:left;
  margin:0;
}

nav.menu ul a {
  display:block;
  padding:25px;
  font-size: 16px;
  font-weight:600;
  text-transform: uppercase;
  color:#fff;
  text-decoration: none;
  transition: all 0.5s ease;
}

nav.menu ul a:hover {
  background:#16a085;
  text-decoration: underline;
}

.sidebar {
  width:275px;
  float:right;
}

.sidebar .widget {
  margin:0 0 25px;
  padding:25px;
  background:#fff;
  transition: all 0.5s ease;
  border-bottom: 2px solid #fff;
}

.sidebar .widget:hover {
  border-bottom: 2px solid #3498db;
}

.sidebar .widget h2 {
  margin:0 0 15px;
  padding:0;
  text-transform: uppercase;
  font-size: 18px;
  font-weight:800;
  color:#3498db;
}

.sidebar .widget p {
  font-size: 14px;
}

.sidebar .widget p:last-child {
  margin:0;
}

.blog {
  float:left;
}

.conteudo {
  width:600px;
  margin:25px auto;
  padding:25px;
  background: #fff;
  border:1px solid #dedede;
  -webkit-box-shadow: 1px 1px 1px 0px rgba(204,204,204,0.35);
  -moz-box-shadow: 1px 1px 1px 0px rgba(204,204,204,0.35);
  box-shadow: 1px 1px 1px 0px rgba(204,204,204,0.35);
}

.conteudo img {
  margin:0 0 25px -25px;
  max-width: 650px;
  min-width: 650px;
}

.conteudo h1 {
  margin:0 0 15px;
  padding:0;
  font-family: Georgia;
  font-weight: normal;
  color: #666;
}

.conteudo p:last-child {
  margin: 0;
}

.conteudo .continue-lendo {
  color:#000;
  font-weight: 700; 
  text-decoration: none;
  transition: all 0.5s ease;
}

.conteudo .continue-lendo:hover {
  margin-left:10px;
}

.post-info {
  float: right;
  margin: -10px 0 15px;
  font-size: 12px;
  text-transform: uppercase;
}

@media screen and (max-width: 960px) {
  
  .header {
  position:inherit;
}
  
.wrap {
  width: 90%;
  margin:25px auto;
}
.sidebar {
  width:100%;
  float:right;
    margin:25px 0 0;
}
  
 .sidebar .widget {
  padding:5%;
}
  
  nav.menu ul {
  width: 100%;
}
  
    nav.menu ul {
  float:inherit;
}
  
  nav.menu ul li {
  float:inherit;
  margin:0;
}
  
nav.menu ul a {
  padding:15px;
  font-size: 16px;
  border-bottom:1px solid #16a085;
  border-top:1px solid #1abf9f;
}
  
.blog {
  width:90%;
}
  
.conteudo {
  float:inherit;
  width:101%;
  padding:5%;  
  margin:0 auto 25px;
  background: #fff;
  border:1px solid #dedede;
}

.conteudo img {
  margin:0 0 25px -5%;
  max-width: 110%;
  min-width: 110%;
}
  
    .conteudo .continue-lendo:hover {
  margin-left:0;
}


}

@media screen and (max-width: 460px) {
 
  nav.menu ul a {
  padding:15px;
  font-size: 14px;
}
  
.sidebar {
  display:none
}
  .post-info {
  display:none;
}
  
  .conteudo {
  margin:25px auto;
  }
  
  .conteudo img {
  margin:-5% 0 25px -5%;
}
}

在views.py編寫主頁測試代碼

# -*- coding: utf-8 -*-
#!/usr/bin/env python

from app import app
from flask import render_template, url_for

@app.route('/')
def index():
    return render_template('welcome.html', title="Welcome")

@app.route('/home')
def home():
    return render_template('base.html', title="Home")

打開瀏覽器, 訪問http://127.0.0.1:5000/home, 你會看到精美小清新的主頁框架

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,156評論 6 529
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 97,866評論 3 413
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 174,880評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,398評論 1 308
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,202評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,743評論 1 320
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,822評論 3 438
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 41,962評論 0 285
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,476評論 1 331
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,444評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,579評論 1 365
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,129評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,840評論 3 344
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,231評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,487評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,177評論 3 388
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,568評論 2 370

推薦閱讀更多精彩內容