flask

flaskStudy 

环境:anaconda (python3.7), windows10

hello world

首先创建三个目录

  • app
  • app/templates :放模板文件(html)
  • app/static:静态资源(图片,css,js等)
  • 创建几个文件
  • run.py:项目启动文件(入口文件)
  • migrate.py:数据库迁移文件
  • app/__init__.py
  • app/config.py:配置文件
  • app/models.py:模型文件
  • app/views.py:视图文件(将来主要的逻辑处理文件)

创建完成后就是这样的:

__init__.py中的代码:

from flask import Flask

app = Flask(__name__)
app.config.from_object('app.config')
from app import views, models

views.py:

from app import app

@app.route('/')
@app.route('/index')
def index():
    return 'hello world'

run.py:

from app import app

app.run(debug=True)

然后运行run.py

你就可以按照提示访问了

Flask 中的数据库

我们将使用 Flask-SQLAlchemy 扩展来管理我们应用程序的数据。这个扩展封装了 SQLAlchemy 项目,这是一个 对象关系映射器 或者 ORM。

ORMs 允许数据库应用程序与对象一起工作,而不是表以及 SQL。执行在对象的操作会被 ORM 翻译成数据库命令。这就意味着我们将不需要学习 SQL,我们将让 Flask-SQLAlchemy 代替 SQL。

conda config --add channels conda-forge
conda install flask-sqlalchemy
 

迁移

我见过的大多数数据库教程会涉及到创建和使用一个数据库,但没有充分讲述随着应用程序扩大更新数据库的问题。通常情况下,每次你需要进行更新,你最终不得不删除旧的数据库和创建一个新的数据库,并且失去了所有的数据。如果数据不能容易地被重新创建,你可能会被迫自己编写导出和导入脚本。

幸运地,我们还有一个更好的选择。

我们将使用 SQLAlchemy-migrate 来跟踪数据库的更新。它只是在开始建立数据库的时候多花费些工作,这只是很小的代价,以后就再不用担心人工数据迁移了

conda install flask-migrate

博客和后台

包含一个博客上传的后台,首页列表,详情页:

__init__.py:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
import os, pymysql
pymysql.install_as_MySQLdb()

app = Flask(__name__)
app.config.from_object('app.config')
db = SQLAlchemy(app)
migrate = Migrate(app, db)

from app import views, models
from app import adminviews
View Code

config.py:

import os

basedir = os.path.abspath(os.path.dirname(__file__))

MYSQL_HOST = "127.0.0.1"
MYSQL_USER = "root"
MYSQL_PWD = "123456"
MYSQL_DB = "test"

SQLALCHEMY_DATABASE_URI = "mysql://" + MYSQL_USER + ":" + MYSQL_PWD + "@" + MYSQL_HOST + "/" + MYSQL_DB
SQLALCHEMY_MIGRATE_REPO = os.path.join(basedir, 'db_repository')
SQLALCHEMY_TRACK_MODIFICATIONS = True


UPLOAD_FOLDER = os.path.join(basedir, 'static/images')
IMGURL = 'http://10.0.0.87:5000/'

SECRET_KEY = '_5#y2L"F4Q8z
xec]/'
View Code

adminviews.py

from app import app, models
from flask import (render_template, request, jsonify, flash, get_flashed_messages)
from werkzeug.utils import secure_filename
import json
import os
import uuid
from . import db

ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'])


@app.route('/')
@app.route('/admin/blogUpload', methods=['GET', 'POST'])
def blogUploadView():
    if request.method == 'POST':
        if request.form['content'].strip() == '' or request.form['category'].strip() == '' or request.form[
            'title'].strip() == '':
            print(request.form['content'])
            flash('信息不全')
        else:
            try:
                blog = models.Blog(**request.form)
                db.session.add(blog)
                db.session.commit()
                flash('成功')
            except:
                db.session.rollback()
                flash('信息有误')

    categorys = models.Category.query.all()
    return render_template('blogUpload.html', categorys=categorys)


@app.route('/img/upload', methods=['GET', 'POST'])
def imgUpload():
    if request.method == 'POST':
        if 'file' not in request.files:
            return jsonify({'code': 0, 'msg': '失败'})
        file = request.files['file']

        if file.filename == '':
            return jsonify({'code': 0, 'msg': '失败'})
        if allowed_file(file.filename):
            filename = str(uuid.uuid1()) + secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            link = app.config['IMGURL'] + filename
            rsp = {'errno': 0, 'data': [link]}
            return jsonify(rsp)
    return jsonify({'code': 0, 'msg': '失败'})




def allowed_file(filename):
    return '.' in filename and 
           filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
View Code

models.py:

from app import db


class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    nickname = db.Column(db.String(64), index=True, unique=True)
    email = db.Column(db.String(120), index=True, unique=True)
    posts = db.relationship('Post', backref='author', lazy='dynamic')

    def __repr__(self):
        return '<User %r>' % (self.nickname)


class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    body = db.Column(db.String(140))
    timestamp = db.Column(db.DateTime)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))

    def __repr__(self):
        return '<Post %r>' % (self.body)


class Category(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(255))

    def __repr__(self):
        return '<Category %r>' % (self.name)


class Blog(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(225), unique=True)
    category = db.Column(db.Integer, db.ForeignKey('category.id'))
    content = db.Column(db.Text)

    def __int__(self, title, category, content):
        self.title = title
        self.category = category
        self.content = content


    def __repr__(self):
        return '<Blog %r>' % (self.title)
View Code

views.py:

from app import app
from flask import render_template
from app import models
from bs4 import BeautifulSoup



@app.route('/')
@app.route('/index')
def index():
    blogs = models.Blog.query.all()
    blogs1 = list()
    for bl in blogs:
        soup = BeautifulSoup(bl.content, "html.parser")
        bf = soup.get_text()[0:10] + '...'
        blogs1.append({"title": bl.title, "bf": bf, "id": bl.id})
    return render_template("index.html", blogs=blogs1)

@app.route('/about/<int:id>')
def about(id):
    about = models.Blog.query.filter_by(id=id).first()
    return render_template("about.html", about=about)
View Code

base.html:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>首页_杨青个人博客 - 一个站在web前端设计之路的女技术员个人博客网站</title>
<meta name="keywords" content="个人博客,杨青个人博客,个人博客模板,杨青" />
<meta name="description" content="杨青个人博客,是一个站在web前端设计之路的女程序员个人网站,提供个人博客模板免费资源下载的个人原创网站。" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="{{ url_for('static',filename='css/base.css') }}" rel="stylesheet">
<link href="{{ url_for('static',filename='css/index.css') }}" rel="stylesheet">
<link href="{{ url_for('static',filename='css/m.css') }}" rel="stylesheet">
<script src="{{ url_for('static',filename='js/jquery.min.js') }}" type="text/javascript"></script>
<script type="text/javascript" src="{{ url_for('static',filename='js/comm.js') }}"></script>
<!--[if lt IE 9]>
<script src="{{ url_for('static',filename='js/modernizr.js') }}"></script>
<![endif]-->
    {% block head %}  {% endblock %}
</head>
<body>
<header class="header-navigation" id="header">
  <nav><div class="logo"><a href="/">杨青个人博客</a></div>
    <h2 id="mnavh"><span class="navicon"></span></h2>
    <ul id="starlist">
      <li><a href="index.html">网站首页</a></li>
      <li><a href="share.html">我的相册</a></li>
      <li><a href="list.html">我的日记</a></li>
      <li><a href="about.html">关于我</a></li>
      <li><a href="gbook.html">留言</a></li>
      <li><a href="info.html">内容页</a></li>
      <li><a href="infopic.html">内容页</a></li>
    </ul>
</nav>
</header>
<article>
  <aside class="l_box">
      <div class="about_me">
        <h2>关于我</h2>
        <ul>
          <i><img src="images/4.jpg"></i>
          <p><b>杨青</b>,一个80后草根女站长!09年入行。一直潜心研究web前端技术,一边工作一边积累经验,分享一些个人博客模板,以及SEO优化等心得。</p>
        </ul>
      </div>
      <div class="wdxc">
        <h2>我的相册</h2>
        <ul>
          <li><a href="/"><img src="images/7.jpg"></a></li>
          <li><a href="/"><img src="images/8.jpg"></a></li>
          <li><a href="/"><img src="images/9.jpg"></a></li>
          <li><a href="/"><img src="images/10.jpg"></a></li>
          <li><a href="/"><img src="images/11.jpg"></a></li>
          <li><a href="/"><img src="images/12.jpg"></a></li>
        </ul>
      </div>
      <div class="search">
        <form action="/e/search/index.php" method="post" name="searchform" id="searchform">
          <input name="keyboard" id="keyboard" class="input_text" value="请输入关键字词" style="color: rgb(153, 153, 153);" onfocus="if(value=='请输入关键字词'){this.style.color='#000';value=''}" onblur="if(value==''){this.style.color='#999';value='请输入关键字词'}" type="text">
          <input name="show" value="title" type="hidden">
          <input name="tempid" value="1" type="hidden">
          <input name="tbname" value="news" type="hidden">
          <input name="Submit" class="input_submit" value="搜索" type="submit">
        </form>
      </div>
      <div class="fenlei">
        <h2>文章分类</h2>
        <ul>
          <li><a href="/">学无止境(33)</a></li>
          <li><a href="/">日记(19)</a></li>
          <li><a href="/">慢生活(520)</a></li>
          <li><a href="/">美文欣赏(40)</a></li>
        </ul>
      </div>
      <div class="tuijian">
        <h2>站长推荐</h2>
        <ul>
          <li><a href="/">你是什么人便会遇上什么人</a></li>
          <li><a href="/">帝国cms 列表页调用子栏目,没有则不显示栏目名称</a></li>
          <li><a href="/">第二届 优秀个人博客模板比赛参选活动</a></li>
          <li><a href="/">个人博客模板《绅士》后台管理</a></li>
          <li><a href="/">你是什么人便会遇上什么人</a></li>
          <li><a href="/">帝国cms 列表页调用子栏目,没有则不显示栏目名称</a></li>
          <li><a href="/">第二届 优秀个人博客模板比赛参选活动</a></li>
          <li><a href="/">个人博客模板《绅士》后台管理</a></li>
        </ul>
      </div>
      <div class="links">
        <h2>友情链接</h2>
        <ul>
          <a href="http://www.yangqq.com">杨青个人博客</a> <a href="http://www.yangqq.com">杨青博客</a>
        </ul>
      </div>
      <div class="guanzhu">
        <h2>关注我 么么哒</h2>
        <ul>
          <img src="images/wx.jpg">
        </ul>
      </div>
  </aside>
  {% block main %}{% endblock %}
</article>
<footer>
  <p>Design by <a href="http://www.yangqq.com" target="_blank">杨青个人博客</a> <a href="/">蜀ICP备11002373号-1</a></p>
</footer>
<a href="#" class="cd-top">Top</a>
</body>
{% block js %}{% endblock %}
</html>
View Code

index.html

{% extends 'base.html'  %}
{% block main %}
<main class="r_box">
    <li>
        {% for bl in blogs %}
      <h3><a href="/about/{{ bl.id }}">{{ bl.title }}</a></h3>
      <p>{{ bl.bf }}</p>
        {% endfor %}
    </li>
  </main>

{% endblock %}
View Code

about.html

{% extends 'base.html'  %}
{% block main %}
<main class="r_box">
     <div class="about">
        {{ about.content | safe }}
     </div>
  </main>

{% endblock %}
View Code

blogUpload.html

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="stylesheet" href="{{ url_for('static',filename='bootstrap337/css/bootstrap.css') }}">
    <link rel="stylesheet" href="{{ url_for('static',filename='editor/release/wangEditor.css') }}">

    <script src="{{ url_for('static',filename='js/jquery.min.js') }}" type="text/javascript"></script>
    <script src="{{ url_for('static',filename='bootstrap337/js/bootstrap.js') }}" type="text/javascript"></script>
    <script src="{{ url_for('static',filename='editor/release/wangEditor.js') }}" type="text/javascript"></script>

</head>
<body>
<div class="container-fluid">
    <div class="row">
        <form class="form-horizontal" action="/admin/blogUpload" method="post">
            {% with messages = get_flashed_messages() %}
            <div class="form-group">
                {% for msg in messages %}
                <span>{{ msg }}</span>
                {% endfor %}
            </div>
            {% endwith %}
            <div class="form-group">
                <label class="col-sm-2 control-label">标题</label>
                <div class="col-sm-10">
                    <input type="text" class="form-control" name="title">
                </div>
            </div>
            <div class="form-group">
                <label class="col-sm-2 control-label">分类</label>
                <div class="col-sm-10">
                    <select name="category" class="form-control">
                        {% for category in categorys %}
                        <option value="{{ category.id }}">{{ category.name }}</option>
                        {% endfor %}
                    </select>
                </div>
            </div>
            <div class="form-group">
                <label class="col-sm-2 control-label">内容</label>
                <div class="col-sm-10">
                    <input type="hidden" class="form-control" name="content" id="content">
                    <div id="edit"></div>
                </div>
            </div>
            <div class="form-group">
                <div class="col-sm-offset-2 col-sm-10">
                    <button type="submit" class="btn btn-default" id="submit">save</button>
                </div>
            </div>
        </form>
    </div>
</div>
<script type="text/javascript">
    var E = window.wangEditor
    var editor = new E('#edit')
     editor.customConfig.menus = [
    'head',  // 标题
    'bold',  // 粗体
    'italic',  // 斜体
    'underline',  // 下划线
    'strikeThrough',  // 删除线
    'foreColor',  // 文字颜色
    'backColor',  // 背景颜色
    'link',  // 插入链接
    'list',  // 列表
    'quote',  // 引用
    'image',  // 插入图片
    'video',  // 插入视频
    'undo',  // 撤销
    'redo'  // 重复
    ]
    editor.customConfig.uploadImgServer = '/img/upload'
    editor.customConfig.uploadFileName = 'file'
    editor.create()

    $('#submit').click(function() {
        var info = editor.txt.html();
        if(!info){
            alert('详情不能为空');
            return false;
        }
       $('#content').val(info);
       return true;
    })

</script>
</body>
</html>
View Code

相关代码在https://github.com/LeeDF/flaskStudy






原文地址:https://www.cnblogs.com/leescre/p/9931836.html