連接數據庫
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>