最近学习python,本来计划今天写一下phthon的一些集合的运用包括函数的运用,但是在学习flask的时候,发现他的网站的东西有一些错误,导致初学者如果学习起来会出问题,尽管我也是一个初学者,但是我不希望接下来的人再继续出这个问题了,就把一个python搭建一个简单的web项目来搭建出来。
看目录之前先下载一些框架,我是在python3.6的基础下安装的,如果你需要别的,自己百度一下吧。
pip install Flask
pip install flask-mysql
这个项目没有所谓的三层架构,就有一层,结果目录如下
工具是pyCharm,新建一个项目-flask-mysqldb,文件目录如下:
flask-mysqldb
examples
static
templates
flask_mysqldb
假定你已经本地安装了mysql,那么直接就可以开始操作了,在flask_mysqldb下新建init.py文件,来连接数据库
import MySQLdb
from MySQLdb import cursors
from flask import _app_ctx_stack, current_app
class MySQL(object):
def __init__(self, app=None):
self.app = app
if app is not None:
self.init_app(app)
def init_app(self, app):
app.config.setdefault('MYSQL_HOST', 'localhost')
app.config.setdefault('MYSQL_USER', 'root')
app.config.setdefault('MYSQL_PASSWORD', '******')
app.config.setdefault('MYSQL_DB', 't_app_info')
app.config.setdefault('MYSQL_PORT', 3306)
app.config.setdefault('MYSQL_UNIX_SOCKET', None)
app.config.setdefault('MYSQL_CONNECT_TIMEOUT', 10)
app.config.setdefault('MYSQL_READ_DEFAULT_FILE', None)
app.config.setdefault('MYSQL_USE_UNICODE', True)
app.config.setdefault('MYSQL_CHARSET', 'utf8')
app.config.setdefault('MYSQL_SQL_MODE', None)
app.config.setdefault('MYSQL_CURSORCLASS', None)
app.config.setdefault('USERNAME','menghaibin')
app.config.setdefault('PASSWORD','123')
app.config['SECRET_KEY'] = 'nihao'
if hasattr(app, 'teardown_appcontext'):
app.teardown_appcontext(self.teardown)
@property
def connect(self):
kwargs = {}
if current_app.config['MYSQL_HOST']:
kwargs['host'] = current_app.config['MYSQL_HOST']
if current_app.config['MYSQL_USER']:
kwargs['user'] = current_app.config['MYSQL_USER']
if current_app.config['MYSQL_PASSWORD']:
kwargs['passwd'] = current_app.config['MYSQL_PASSWORD']
if current_app.config['MYSQL_DB']:
kwargs['db'] = current_app.config['MYSQL_DB']
if current_app.config['MYSQL_PORT']:
kwargs['port'] = current_app.config['MYSQL_PORT']
if current_app.config['MYSQL_UNIX_SOCKET']:
kwargs['unix_socket'] = current_app.config['MYSQL_UNIX_SOCKET']
if current_app.config['MYSQL_CONNECT_TIMEOUT']:
kwargs['connect_timeout'] = \
current_app.config['MYSQL_CONNECT_TIMEOUT']
if current_app.config['MYSQL_READ_DEFAULT_FILE']:
kwargs['read_default_file'] = \
current_app.config['MYSQL_READ_DEFAULT_FILE']
if current_app.config['MYSQL_USE_UNICODE']:
kwargs['use_unicode'] = current_app.config['MYSQL_USE_UNICODE']
if current_app.config['MYSQL_CHARSET']:
kwargs['charset'] = current_app.config['MYSQL_CHARSET']
if current_app.config['MYSQL_SQL_MODE']:
kwargs['sql_mode'] = current_app.config['MYSQL_SQL_MODE']
if current_app.config['MYSQL_CURSORCLASS']:
kwargs['cursorclass'] = getattr(cursors, current_app.config['MYSQL_CURSORCLASS'])
return MySQLdb.connect(**kwargs)
@property
def connection(self):
ctx = _app_ctx_stack.top
if ctx is not None:
if not hasattr(ctx, 'mysql_db'):
ctx.mysql_db = self.connect
return ctx.mysql_db
def teardown(self, exception):
ctx = _app_ctx_stack.top
if hasattr(ctx, 'mysql_db'):
ctx.mysql_db.close()
设置config的值的时候,可以使用app.config[‘SECRET_KEY’] = ‘123’,也可以app.config.setdefault(‘PASSWORD’,’123’),这两种设置都可以的,连接数据库的配置就不多说了,各个配置代表什么,基本了解数据库的人也都懂,反正我们基本用到的无非就是一个地址,数据库,超时时间,编码格式这些。
在examples文件夹下新建app.py,然后复制如下代码到文件中
from flask import Flask, request, session, redirect, url_for, abort, \
render_template, flash
from flask_mysqldb import MySQL
app = Flask(__name__)
mysql = MySQL(app)
#获取数据库
def get_db():
return mysql.connection.cursor()
#首页
@app.route('/show_entries')
def show_entries():
cur = get_db()
cur.execute('select title, text from entries order by id desc')
entries = [dict(title=row[0], text=row[1]) for row in cur.fetchall()]
return render_template('show_entries.html', entries=entries)
#登录页
@app.route('/login', methods=['GET', 'POST'])
def login():
error = None
if request.method == 'POST':
if request.form['username'] != app.config['USERNAME']:
error = 'Invalid username'
elif request.form['password'] != app.config['PASSWORD']:
error = 'Invalid password'
else:
session['logged_in'] = True
flash('You were logged in')
return redirect(url_for('show_entries'))
return render_template('login.html', error=error)
#添加条目
@app.route('/add_entry', methods=['POST'])
def add_entry():
cur = get_db()
if not session.get('logged_in'):
abort(401)
title = str(request.form['title'])
text = str(request.form['text'])
print()
cur.execute('insert into entries (title, text) values (%s, %s)',
[title,text])
mysql.connection.commit()
flash('New entry was successfully posted')
return redirect(url_for('show_entries'))
#退出登录
@app.route('/logout')
def logout():
session.pop('logged_in', None)
flash('You were logged out')
return redirect(url_for('show_entries'))
if __name__ == '__main__':
app.run(debug=True)
各个业务名称已经在文件中标明了,就不再说了,但是大家注意到了url_for这个方法,这个方法比较坑了
url_for()函数是用于构建指定函数的URL,也就是说他找的是函数,而不是route这个路由的路径,所以你一定要写函数名称,否则回报这个错误
werkzeug.routing.BuildError: Could not build url for endpoint ‘show_entries’. Did you mean ‘add_entry’ instead?
折腾了我一个小时,才发现在flask的官网他都没有管这个,结果一直报错
在templates文件夹中创建login.html.
{% extends "layout.html" %}
{% block body %}
<h2>Loginh2>
{% if error %}<p class=error><strong>Error:strong> {{ error }}{% endif %}
<form action="{{ url_for('login') }}" method=post>
<dl>
<dt>Username:
<dd><input type=text name=username>
<dt>Password:
<dd><input type=password name=password>
<dd><input type=submit value=Login>
dl>
form>
{% endblock %}
在templates文件夹中添加logout.html
<title>Flaskrtitle>
<link rel=stylesheet type=text/css href="{{ url_for('static', filename='style.css') }}">
<div class=page>
<h1>Flaskrh1>
<div class=metanav>
{% if not session.logged_in %}
<a href="{{ url_for('login') }}">log ina>
{% else %}
<a href="{{ url_for('logout') }}">log outa>
{% endif %}
div>
{% for message in get_flashed_messages() %}
<div class=flash>{{ message }}div>
{% endfor %}
{% block body %}{% endblock %}
div>
在templates文件夹中创建show_entries.html文件
{% extends "layout.html" %}
{% block body %}
{% if session.logged_in %}
<form action="{{ url_for('add_entry') }}" method=post class=show_entries>
<dl>
<dt>Title:
<dd><input type=text size=30 name=title>
<dt>Text:
<dd><textarea name=text rows=5 cols=40>textarea>
<dd><input type=submit value=Share>
dl>
form>
{% endif %}
<ul class=entries>
{% for entry in entries %}
<li><h2>{{ entry.title }}h2>{{ entry.text|safe }}
{% else %}
<li><em>Unbelievable. No entries here so farem>
{% endfor %}
ul>
{% endblock %}
debug运行,访问http://localhost:5000/show_entries我们大概能看到如下的界面,
如果能看到这个界面,基本就算是成功了,至于代码里边各个方法,各个模块都是是吗功能,我也不知道,自己查吧。
源码下载地址: mysql-flask下载地址