作者:Julian @ 恆馨博客
轉載:https://towait.com/blog/flask-mongodb-crud/
本文記錄一下完整的適用於python3.5+mongodb3.4的一個簡單的數據庫操作實例.
PS: 這是一個非常非常簡單的基礎實例,不合理的地方不少,僅供學習參考.
開發環境
Vagrant(CentOS7 + Python 3.5 + MongoDB 3.4) + XShell + Windows 10 + Sublime Text 2
數據庫環境
- 主機: localhost (默認)
- 端口: 27017 (默認)
- 數據庫名: todolist
- 集合: todos
- 用戶名: todo
- 密碼: towait.com
數據庫及賬戶的創建
根據我爬文若干的經驗來看,網上的flask+mongodb教程基本上是MongoDB默認安裝沒有經過安全認證的配置,數據庫連接不需要用戶名和密碼,在這篇MongoDB數據庫的安裝及基本配置使用(CentOS7)文章中我曾經強調要做security參數的安全配置,具體操作訪問前面的鏈接內容即可,本文使用的是需要數據庫用戶名和密碼登錄的場景.
下面直接我們進入正題
首先使用用戶管理員
賬號登錄MongoDB數據庫
mongo -u admin -p --authenticationDatabase admin
注意,這里使用的是用戶管理員的賬號登錄,這個賬戶在在MongoDB安裝的時候應該被配置好的.
創建數據庫
創建一個名為"todolist
"的數據庫
use todolist
創建用戶
創建用戶名為"todo
"密碼為"towait.com
"並擁有數據庫讀寫權限的賬戶
db.createUser({user: "todo", pwd: "towait.com", roles:[{role: "readWrite", db: "todolist"}]})
驗證賬戶
創建成功后使用 quit()
命令退出當前賬戶並使用剛剛創建的賬戶登錄到todolist數據庫
mongo -u todo -p --authenticationDatabase todolist
登錄成功后默認為test數據庫,使用 use todolist
切換到目標數據庫
創建集合
我們需要創建一個名為todos
的集合
db.createCollection("todos", {capped: false})
至此已經成功創建了數據庫/用戶名/密碼/集合等所需要的數據庫信息.
更多數據庫管理的相關命令在<MongoDB數據庫管理常用命令>這篇文章里面均有記錄,也可以翻閱參考.
Flask主程序
程序文件目錄機構
todolist
----app.py
----templates
--------index.html
--------base.html
/app.py
from flask import Flask, jsonify, request, abort,url_for,render_template,redirect from time import time from bson.objectid import ObjectId from bson.json_util import dumps from flask_pymongo import PyMongo app = Flask(__name__) app.config['MONGO_DBNAME'] = 'todolist' app.config['MONGO_URI'] = 'mongodb://todo:towait.com@localhost:27017/todolist' app.url_map.strict_slashes = False mongo = PyMongo(app) @app.route("/", methods=['GET']) def home_page(): return "<h1>Hello World!</h1>" class Todo(object): @classmethod def create_doc(cls, content): return { 'content': content, 'created_at': time(), 'is_finished': False, 'finished_at': None } @app.route('/todo/',methods=['GET']) def index(): todos = mongo.db.todos.find({}) return render_template('index.html',todos=todos) @app.route('/todo/', methods=['POST']) def add(): content = request.form.get('content', None) if not content: abort(400) mongo.db.todos.insert(Todo.create_doc(content)) return redirect('/todo/') @app.route('/todo/<content>/finished') def finish(content): result = mongo.db.todos.update_one( {'content':content}, { '$set': { 'is_finished': True, 'finished_at': time() } } ) return redirect('/todo/') @app.route('/todo/<content>') def delete(content): result = mongo.db.todos.delete_one( {'content':content} ) return redirect('/todo/') @app.route('/todo/search/<content>') def find(content): todos = mongo.db.todos.find( {'content': {"$regex": content}} ) return render_template('index.html', todos=todos) if __name__ == '__main__': app.run(debug=True)
/templates/index.html
{% extends 'base.html' %}
{% block content %}
<form action="{{ url_for('index') }}" method=post class=add-entry> <h2>todo list:</h2> <textarea name=content rows=2 cols=20></textarea> <input type=submit value=submit> </form> <ul> {% for todo in todos %} <li><p>{{todo.content}} <a href="{{ url_for('delete',content=todo.content)}}">delete</a>  <a href="{{ url_for('finish',content=todo.content)}}">done</a></p> {%- if todo.is_finished -%} <p>finished</p> {%- else-%} <p>unfinished</p> {%- endif %} </li> {% endfor %} </ul> {% endblock %}
/templates/base.html
<!DOCTYPE html>
<html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta content="width=device-width, initial-scale=1.0" name="viewport"/> </head> <body> {% block content %} {% endblock %} </body> </html>
運行實例
切換至程序目錄運行
python app.py
由於我在vagrant環境中運行,使用python命令運行發現端口沒有轉發到宿主電腦中,這個問題在Flask在Vagrant中端口轉發失敗的解決方法一文中特地有說明,啟動flask時需要加--host參數,於是有了下面的啟動方法
export FLASK_APP=app.py
flask run --host=0.0.0.0
啟動后你可以使用 http://127.0.0.1:5000
在本地訪問(我映射的端口是5050),訪問根目錄返回的應該是"hello world"的歡迎頁,訪問/todo/ 目錄應該會出現相關表單內容,你可以刪除或者設置任務狀態,入下圖
訪問URL http://127.0.0.1:5000/todo/search/{$keyword}
可以對關鍵詞的模糊搜索。