25.1.发布帖子后台逻辑完成
(1)apps/models.py
class PostModel(db.Model): __tablename__ = ‘post‘ id = db.Column(db.Integer, primary_key=True, autoincrement=True) title = db.Column(db.String(200), nullable=False) content = db.Column(db.Text, nullable=False) create_time = db.Column(db.DateTime, default=datetime.now) board_id = db.Column(db.Integer, db.ForeignKey(‘board.id‘)) board = db.relationship(‘BoardModel‘, backref=‘posts‘)
(2)front/decorater.py
from flask import session,redirect,url_for from functools import wraps import config def login_requried(func): @wraps(func) def wrapper(*args,**kwargs): if config.FRONT_USER_ID in session: return func(*args,**kwargs) else: return redirect(url_for(‘front.signin‘)) return wrapper
(3)front/forms.py
class AddPostForm(BaseForm): title=StringField(validators=[InputRequired(message=‘请输入标题‘)]) content=StringField(validators=[InputRequired(message=‘请输入内容‘)]) board_id=IntegerField(validators=[InputRequired(message=‘请选择版块‘)])
(4)front/views.py
@bp.route(‘/apost/‘, methods=[‘POST‘, ‘GET‘]) @login_requried def apost(): if request.method == ‘GET‘: boards = BoardModel.query.all() return render_template(‘front/front_apost.html‘, boards=boards) else: form = AddPostForm(request.form) if form.validate(): title = form.title.data content = form.content.data board_id = form.board_id.data board = BoardModel.query.get(board_id) if not board: return restful.params_error(message=‘没有这个版块‘) post = PostModel(title=title, content=content, board_id=board_id) post.board = board db.session.add(post) db.session.commit() return restful.success() else: return restful.params_error(message=form.get_error())
25.2.发布帖子界面布局完成
(1)把ueditor静态文件放到static目录下
(2)apps目录下新建ueditor目录
init.py
from .ueditor import bp
ueditor.py
#encoding: utf-8 from flask import ( Blueprint, request, jsonify, url_for, send_from_directory, current_app as app ) import json import re import string import time import hashlib import random import base64 import sys import os from urllib import parse # 更改工作目录。这么做的目的是七牛qiniu的sdk # 在设置缓存路径的时候默认会设置到C:/Windows/System32下面 # 会造成没有权限创建。 os.chdir(os.path.abspath(sys.path[0])) try: import qiniu except: pass from io import BytesIO bp = Blueprint(‘ueditor‘,__name__,url_prefix=‘/ueditor‘) UEDITOR_UPLOAD_PATH = "" UEDITOR_UPLOAD_TO_QINIU = False UEDITOR_QINIU_ACCESS_KEY = "" UEDITOR_QINIU_SECRET_KEY = "" UEDITOR_QINIU_BUCKET_NAME = "" UEDITOR_QINIU_DOMAIN = "" @bp.before_app_first_request def before_first_request(): global UEDITOR_UPLOAD_PATH global UEDITOR_UPLOAD_TO_QINIU global UEDITOR_QINIU_ACCESS_KEY global UEDITOR_QINIU_SECRET_KEY global UEDITOR_QINIU_BUCKET_NAME global UEDITOR_QINIU_DOMAIN UEDITOR_UPLOAD_PATH = app.config.get(‘UEDITOR_UPLOAD_PATH‘) if UEDITOR_UPLOAD_PATH and not os.path.exists(UEDITOR_UPLOAD_PATH): os.mkdir(UEDITOR_UPLOAD_PATH) UEDITOR_UPLOAD_TO_QINIU = app.config.get("UEDITOR_UPLOAD_TO_QINIU") if UEDITOR_UPLOAD_TO_QINIU: try: UEDITOR_QINIU_ACCESS_KEY = app.config["UEDITOR_QINIU_ACCESS_KEY"] UEDITOR_QINIU_SECRET_KEY = app.config["UEDITOR_QINIU_SECRET_KEY"] UEDITOR_QINIU_BUCKET_NAME = app.config["UEDITOR_QINIU_BUCKET_NAME"] UEDITOR_QINIU_DOMAIN = app.config["UEDITOR_QINIU_DOMAIN"] except Exception as e: option = e.args[0] raise RuntimeError(‘请在app.config中配置%s!‘%option) csrf = app.extensions.get(‘csrf‘) if csrf: csrf.exempt(upload) def _random_filename(rawfilename): letters = string.ascii_letters random_filename = str(time.time()) + "".join(random.sample(letters,5)) filename = hashlib.md5(random_filename.encode(‘utf-8‘)).hexdigest() subffix = os.path.splitext(rawfilename)[-1] return filename + subffix @bp.route(‘/upload/‘,methods=[‘GET‘,‘POST‘]) def upload(): action = request.args.get(‘action‘) result = {} if action == ‘config‘: config_path = os.path.join(bp.static_folder or app.static_folder,‘ueditor‘,‘config.json‘) with open(config_path,‘r‘,encoding=‘utf-8‘) as fp: result = json.loads(re.sub(r‘/*.**/‘,‘‘,fp.read())) elif action in [‘uploadimage‘,‘uploadvideo‘,‘uploadfile‘]: image = request.files.get("upfile") filename = image.filename save_filename = _random_filename(filename) result = { ‘state‘: ‘‘, ‘url‘: ‘‘, ‘title‘: ‘‘, ‘original‘: ‘‘ } if UEDITOR_UPLOAD_TO_QINIU: if not sys.modules.get(‘qiniu‘): raise RuntimeError(‘没有导入qiniu模块!‘) buffer = BytesIO() image.save(buffer) buffer.seek(0) q = qiniu.Auth(UEDITOR_QINIU_ACCESS_KEY, UEDITOR_QINIU_SECRET_KEY) token = q.upload_token(UEDITOR_QINIU_BUCKET_NAME) ret,info = qiniu.put_data(token,save_filename,buffer.read()) if info.ok: result[‘state‘] = "SUCCESS" result[‘url‘] = parse.urljoin(UEDITOR_QINIU_DOMAIN,ret[‘key‘]) result[‘title‘] = ret[‘key‘] result[‘original‘] = ret[‘key‘] else: image.save(os.path.join(UEDITOR_UPLOAD_PATH, save_filename)) result[‘state‘] = "SUCCESS" result[‘url‘] = url_for(‘ueditor.files‘,filename=save_filename) result[‘title‘] = save_filename, result[‘original‘] = image.filename elif action == ‘uploadscrawl‘: base64data = request.form.get("upfile") img = base64.b64decode(base64data) filename = _random_filename(‘xx.png‘) filepath = os.path.join(UEDITOR_UPLOAD_PATH,filename) with open(filepath,‘wb‘) as fp: fp.write(img) result = { "state": "SUCCESS", "url": url_for(‘files‘,filename=filename), "title": filename, "original": filename } return jsonify(result) @bp.route(‘/files/<filename>/‘) def files(filename): return send_from_directory(UEDITOR_UPLOAD_PATH,filename)
(3)perfect_bbs.py
from apps.ueditor import bp as ueditor_bp
app.register_blueprint(ueditor_bp)
(4)front/index.html
<a class="btn btn-warning btn-block" href="{{ url_for(‘front.apost‘) }}" id="add-post-btn">发布帖子</a>
(5)front/apost.html
{% extends ‘front/front_base.html‘ %} {% from ‘common/_macros.html‘ import static %} {% block title %} 发布帖子 {% endblock %} {% block head %} <script src="{{ static(‘ueditor/ueditor.config.js‘) }}"></script> <script src="{{ static(‘ueditor/ueditor.all.min.js‘) }}"></script> <script src="{{ static(‘front/js/front_apost.js‘) }}"></script> {% endblock %} {% block body %} <form method="post"> <div class="form-group"> <div class="input-group"> <span class="input-group-addon">标题</span> <input type="text" name="title" class="form-control"> </div> </div> <div class="form-group"> <div class="input-group"> <span class="input-group-addon">版块</span> <select name="board_id" class="form-control"> {% for board in boards %} <option value="{{ board.id }}">{{ board.name }}</option> {% endfor %} </select> </div> </div> <div class="form-group"> <script id="ueditor" type="text/plain" style="height:500px;"></script> </div> <div class="form-group"> <button class="btn btn-danger" id="submit-btn">发布帖子</button> </div> </form> {% endblock %}
(6)front/js/apost.js
$(function () { var ue=UE.getEditor(‘ueditor‘,{‘serverUrl‘:‘/ueditor/upload/‘}); });