连接数据库
sqlalchemy
- 数据库驱动:
pip install pymysql
或者
pip install sql-connector
- 在flask虚拟环境中安装sqlalchemy
pip install flask-sqlalchemy
默认安装:Successfully installed SQLAlchemy-1.3.8 flask-sqlalchemy-2.4.0
settings.py
class Config:
DEBUG = False
TESTING = False
# mysql+pymysql://user:password@host:port/database
# SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://gjp:[email protected]:3306/test'
SQLALCHEMY_DATABASE_URI = 'mysql+mysqlconnector://root:[email protected]:3306/mydb'
SQLALCHEMY_TRACK_MODIFICATIONS = True
- 安装:
pip install flask-script
a. 设置服务器
原来: python app.py
python app.py runserver -h host -p port ----> 使用脚本命令的方式控制服务器启动
b. 控制sqlachemy数据库
pip install flask-migrate
绑定命令到script上
exts
|-- __init__.py
|
db =SQLAlchemy()
def create_app():
app = Flask(__name__)
...
db.init_app(app)
migrate = Migrate(app=app,db=db)
manager.add_command('命令名',MigrateCommand)
使用命令: db
python app.py db init ----------> 产生一个文件夹 migrations
此文件中存在versions文件夹
versions作用:
保存你做出的各种更改
xxxx.py
xxxx.py
apps:__init__.py
from flask import Flask
from apps.views.blog_view import blog_bp
from exts import db
from settings import DevelopmentConfig
def create_app():
app = Flask(__name__)
app.config.from_object(DevelopmentConfig)
db.init_app(app)
# 注册蓝图
app.register_blueprint(blog_bp,url_prefix='/blog')
return app
exits:__init__.py
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
app.py
from flask_migrate import MigrateCommand, Migrate
from flask_script import Manager
from apps.models.user_model import User
from apps import create_app
from exts import db
app = create_app()
manager = Manager(app)
# 创建数据库命令
migrate = Migrate(app=app, db=db) # db 就是SQLAlchemy对象
manager.add_command('db', MigrateCommand)
if __name__ == '__main__':
# app.run()
manager.run()
apps:models:user_models.py
from exts import db
# db 就是SQLAlchemy
class User(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
username = db.Column(db.String(10), nullable=False)
password = db.Column(db.String(10), nullable=False)
phone = db.Column(db.String(11), nullable=False, unique=True)
def __str__(self):
return self.username
步骤:
- 创建app
- 创建SQLAlchemy并绑定app
- 创建manager并且绑定migrate
- Templates+view+Blueprint
import hashlib
from flask import Blueprint, render_template, request, redirect, url_for
from sqlalchemy import or_
from apps.models.blog_model import User
from exts import db
blog_bp = Blueprint('blog', __name__, url_prefix='/blog')
# 首页
@blog_bp.route('/', endpoint='index')
def index():
return render_template('index.html')
# 用户更新
@blog_bp.route('/update', endpoint='update', methods=['GET', 'POST'])
def user_update():
if request.method == 'GET':
id = request.args.get('id')
user = User.query.get(id) # 要更新的用户对象
return render_template('update.html', user=user)
else:
id = request.form.get('id')
username = request.form.get('username')
phone = request.form.get('phone')
isdelete = request.form.get('isdelete')
user = User.query.get(id) # 要更新的用户对象
user.username = username
user.phone = phone
# isdelete添加判断
db.session.commit()
return redirect(url_for('blog.uall'))
# 用户删除
@blog_bp.route('/delete/<id>', endpoint='delete')
def user_delete(id):
user = User.query.get(id) # 根据主键查找对象
# print(user)
# db.session.delete(user) # 物理删除
user.isdelete = True
db.session.commit()
return redirect(url_for('blog.uall'))
# 用户检索
@blog_bp.route('/search', endpoint='search', methods=['POST'])
def user_search():
search = request.form.get('search')
if search:
# users = User.query.filter(or_(User.username==search,
# User.phone == search)).all() # select * from user where username=search or phone=search
# number = User.query.filter(or_(User.username==search,
# User.phone == search)).count()
users = User.query.filter(or_(User.username.like('%' + search + '%'), User.phone == search)).all()
number = User.query.filter(or_(User.username.like(search), User.phone == search)).count()
return render_template('user_all.html', users=users, number=number)
else:
return redirect(url_for('blog.index'))
# 显示所有用户
@blog_bp.route('/userall', endpoint='uall')
def user_all():
# users = User.query.filter_by(isdelete=False).all()
# users = User.query.filter(User.isdelete == False, User.phone.startswith('150')).order_by(-User.rdatetime)
users = User.query.all()
number = User.query.count()
return render_template('user_all.html', users=users, number=number)
# 用户登录
@blog_bp.route('/login', endpoint='login', methods=['GET', 'POST'])
def user_login():
if request.method == 'POST':
username = request.form.get('username')
pwd1 = request.form.get('password1')
pwd = hashlib.sha1(pwd1.encode('utf-8')).hexdigest()
# 查询
user = User.query.filter_by(username=username).first() # select * from user where username=xxxx
if pwd == user.password:
return '用户登录成功!'
else:
return render_template('login.html', msg='用户名或者密码有误!')
return render_template('login.html')
# 用户注册
@blog_bp.route('/register', endpoint='register', methods=['GET', 'POST'])
def user_register():
if request.method == 'POST':
# 获取表单提交的内容
username = request.form.get('username')
pwd1 = request.form.get('password1')
pwd2 = request.form.get('password2')
phone = request.form.get('phone')
if pwd1 == pwd2:
# 存放到数据库
pwd = hashlib.sha1(pwd1.encode('utf-8')).hexdigest()
print(pwd)
# 添加数据步骤:
# 1. 创建模型对象
user = User()
# 2. 给对象赋值
user.username = username
user.password = pwd
user.phone = phone
# 3. 向数据库提交数据
db.session.add(user)
db.session.commit()
return redirect(url_for('blog.index'))
else:
return render_template('register.html', msg=' 密码不一致')
return render_template('register.html')
删除和更新;
物理删除:
- 根据主键找到要删除user对象
user = User.query.get(id) # 根据主键查找对象 - 利用db.session完成删除操作
db.session.delete(user) - 提交
db.session.commit()
逻辑删除:
- 根据主键找到要删除user对象
user = User.query.get(id) # 根据主键查找对象 - 更改isdelete
user.isdelete=True - 提交更改
db.session.commit()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %} 首页 {% endblock %}</title>
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
<!-- 可选的 Bootstrap 主题文件(一般不用引入) -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap-theme.min.css">
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js"></script>
{% block mycss %} {% endblock %}
</head>
<body>
<nav class="navbar navbar-default">
<div class="container">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">python博客</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="active"><a href="#">首页 <span class="sr-only">(current)</span></a></li>
<li><a href="#">发表博客</a></li>
<li><a href="{{url_for('blog.uall')}}">显示用户</a></li>
</ul>
<form class="navbar-form navbar-left" action="{{url_for('blog.search')}}" method="post">
<div class="form-group">
<input type="text" class="form-control" placeholder="输入用户名/手机号码" name="search">
</div>
<button type="submit" class="btn btn-default">搜索用户</button>
</form>
<ul class="nav navbar-nav navbar-right">
<li><a href="{{url_for('blog.login')}}">登录</a></li>
<li><a href="{{ url_for('blog.register') }}">注册</a></li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
{% block content %} {% endblock %}
{% block myjs %} {% endblock %}
</body>
</html>