我正在构建Flask Web应用程序,并且正在实现一项功能,用户可以上传自己的图像。我正在研究三个文件来实现此功能:
models.py:该文件用于维护数据库结构和可以在数据库内实体上调用的函数。
routes.py:用于处理站点对各种URL上的HTTP请求的响应的文件。
__ init__.py:设置了我所有的配置变量。
我在models.py中有一个名为avatar的函数,该函数返回用户的头像。如果他们还没有上传照片,它将使用gravatars MD5哈希生成器生成化身。我想更改此功能,以便它首先在我的上传文件中查找以查看用户是否上传了照片。
我已设置上传功能,以便将用户的照片保存为..格式的文件夹。我有一个名为UPLOAD_FOLDER的配置变量,该变量存储此文件夹的绝对路径。但是,问题是无法从模型文件访问配置变量。我曾尝试按照docs中所述创建本地上下文,但是遇到KeyError:“ UPLOAD_FOLDER”错误。
models.py
from flask import Flask, current_app
from hashlib import md5
class User(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key = True)
username = db.Column(db.String(64), index = True, unique = True)
email = db.Column(db.String(128), index = True, unique = True, nullable = False)
password_hash = db.Column(db.String(128), nullable = False)
is_admin = db.Column(db.Boolean(), default = False)
polls = db.relationship("Poll", backref = "author", lazy = "dynamic")
votes = db.relationship("Votes", backref = "voter", lazy = "dynamic")
def avatar(self, size):
app = Flask(__name__)
with app.app_context():
UPLOAD_FOLDER = current_app.config["UPLOAD_FOLDER"]
if(UPLOAD_FOLDER):
print("hooray")
digest = md5(self.email.lower().encode("utf-8")).hexdigest()
return(("https://www.gravatar.com/avatar/{}?d=retro&s={}").format(digest, size))
__ init __。py
import os
dirname = os.path.dirname(os.path.abspath(__file__))
UPLOAD_FOLDER = dirname + "/static/user-images/"
ALLOWED_FILES = ["png", "jpeg", "jpg"]
app = Flask(__name__)
app.config.from_object(Config)
app.config["UPLOAD_FOLDER"] = UPLOAD_FOLDER
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
app.config["ALLOWED_FILES"] = ALLOWED_FILES
routes.py
import os
from werkzeug.utils import secure_filename
from flask_login import current_user
def allowed_file(file):
return(file.filename.split(".")[1].lower() in app.config["ALLOWED_FILES"])
@app.route("/upload", methods = ["POST"])
@login_required
def upload_file():
if(request.method == "POST"):
if("file" not in request.files):
print(request.files)
flash("No file part")
return(redirect("upload"))
file = request.files["file"]
if(not file.filename):
flash("No file uploaded!")
return(redirect("upload"))
if(file and allowed_file(file)):
extension = file.filename.split(".")[1]
filename = secure_filename(str(current_user.id) + "." + extension)
file.save(os.path.join(app.config["UPLOAD_FOLDER"], filename))
flash("Files successfully uploaded")
return(redirect(url_for("user", username = current_user.username)))
答案 0 :(得分:0)
为什么不将配置变量推送到应用程序上下文中,为什么不将它们放在配置文件中并在需要时将其导入?
制作一个名为config.py的文件
config.py
import os
dirname = os.path.dirname(os.path.abspath(__file__))
UPLOAD_FOLDER = dirname + "/static/user-images/"
ALLOWED_FILES = ["png", "jpeg", "jpg"]
MAX_CONTENT_LENGTH = 16 * 1024 * 1024
然后在routes.py中导入这些配置变量并使用它们,将app.config["UPLOAD_FOLDER"]
替换为UPLOAD_FOLDER
routes.py
import os
from werkzeug.utils import secure_filename
from flask_login import current_user
from config import UPLOAD_FOLDER
def allowed_file(file):
return(file.filename.split(".")[1].lower() in app.config["ALLOWED_FILES"])
@app.route("/upload", methods = ["POST"])
@login_required
def upload_file():
if(request.method == "POST"):
if("file" not in request.files):
print(request.files)
flash("No file part")
return(redirect("upload"))
file = request.files["file"]
if(not file.filename):
flash("No file uploaded!")
return(redirect("upload"))
if(file and allowed_file(file)):
extension = file.filename.split(".")[1]
filename = secure_filename(str(current_user.id) + "." + extension)
file.save(os.path.join(UPLOAD_FOLDER, filename))
flash("Files successfully uploaded")
return(redirect(url_for("user", username = current_user.username)))
在models.py中执行相同的操作,将current_app.config["UPLOAD_FOLDER"]
替换为UPLOAD_FOLDER
。
models.py
from flask import Flask, current_app
from hashlib import md5
from config import UPLOAD_FOLDER
class User(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key = True)
username = db.Column(db.String(64), index = True, unique = True)
email = db.Column(db.String(128), index = True, unique = True, nullable = False)
password_hash = db.Column(db.String(128), nullable = False)
is_admin = db.Column(db.Boolean(), default = False)
polls = db.relationship("Poll", backref = "author", lazy = "dynamic")
votes = db.relationship("Votes", backref = "voter", lazy = "dynamic")
def avatar(self, size):
app = Flask(__name__)
with app.app_context():
upload_folder = UPLOAD_FOLDER # please don't make normal variables UPPERCASE
if(upload_folder):
print("hooray")
digest = md5(self.email.lower().encode("utf-8")).hexdigest()
return(("https://www.gravatar.com/avatar/{}?d=retro&s={}").format(digest, size))