美文网首页爬虫其他
Flask开发博客(上)

Flask开发博客(上)

作者: Andrew_liu | 来源:发表于2015-05-13 13:21 被阅读38284次

    本博客采用创作共用版权协议, 要求署名、非商业用途和保持一致. 转载本博客文章必须也遵循署名-非商业用途-保持一致的创作共用协议.

    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" href="http://yui.yahooapis.com/pure/0.6.0/pure-min.css">
        <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" href="http://yui.yahooapis.com/pure/0.6.0/pure-min.css">
        <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, 你会看到精美小清新的主页框架

    相关文章

      网友评论

      • 小路_:等更
      • 迷藏_:求下集
      • 86d9ecb48bcf:from flask_script import Manager,Server
      • 扯远大师:下呢?
      • 灰太狼1991:大哥,下集呢,很急很关键
      • Reborn_L:楼主 为什么是在manage.py中为什么不是from app import views

        from app import app是什么意思

        我记得如果在同一个package中 好像可以可以直接import 不知道这样对不对
      • 261254cef73d:@manager.command
        def save_post():
        post = Post(author="Andrew liu",
        title="Hello World",
        tags="test",
        content="This is the First Post")
        to.save()

        在manage.py这里是不是有个错误,应该是post.save()吧
      • 9d2aaa1ffcdf:大神你好,期待下集
      • 云中浪子:写得很精彩,有下集么?
      • AbelSu:第一个页面能进入,但是/home进入不了,配置问题吗?
      • 2d0b9de53f70:没有续集?
      • Andrew_liu: @zhangyi2099 是的,不好意思,打错了
      • Andrew_liu: @zhangyi2099 是的,不好意思,打错了
      • 长物记:python manage.py runserver 才对吧???
      • WeiLShi:好好

      本文标题:Flask开发博客(上)

      本文链接:https://www.haomeiwen.com/subject/fgnfqttx.html