这是models.py
import os
import secrets
class BlogPost(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(40), nullable=False)
content = db.Column(db.Text, nullable=False)
thumbnail = db.Column(db.String(30), nullable=False, default='/static/blog/images/blog_thumbnails/default.png')
date_added = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
hex_token = db.Column(db.String(16), nullable=False, default=secrets.token_hex(8))
def save_thumbnail(self):
if 'thumbnail' in request.files:
file = request.files['thumbnail']
filename = f'{self.id}_{self.hex_token}.png'
file.save(os.path.join(current_app.config['UPLOAD_FOLDER'], filename))
然后routes.py
中有一个视图函数,用于添加一个新的BlogPost
对象,该对象看起来像这样:
@admin_blueprint.route('/add_blog/', methods=['GET', 'POST'])
def add_blog():
if request.method == "POST":
title = request.form['title']
content = request.form['content']
post = BlogPost(title=title, content=content)
db.session.add(post)
db.session.commit()
post.save_thumbnail()
db.session.close()
return redirect(url_for('blog.index'))
form = BlogPostForm()
return render_template('add_blog.html', form=form)
thumbnail
模型的BlogPost
字段只是用户上传图片的路径,文件名由BlogPost
对象的ID加上下划线和随机十六进制标记生成然后使用.save()
方法保存图片,但是,假设用户在一个会话中创建了多个BlogPost
对象,文件名将仅具有唯一的ID,而没有十六进制,并且从python shell中的使用方式与好吧。
例如,生成的文件名将如下所示:
1_e5d2e3623a42f117
,2_e5d2e3623a42f117
,3_e5d2e3623a42f117
等...
我认为解决方法是向save_thumbnail
方法中添加一个hex_token参数,从模型中完全删除hex_token
字段,而是在每次调用视图时生成它。这就是我的意思:
def save_thumbnail(self, hex_token):
if 'thumbnail' in request.files:
file = request.files['thumbnail']
filename = f'{self.id}_{hex_token}.png'
file.save(os.path.join(current_app.config['UPLOAD_FOLDER'], filename))
和routes.py
@admin_blueprint.route('/add_blog/', methods=['GET', 'POST'])
def add_blog():
if request.method == "POST":
title = request.form['title']
content = request.form['content']
post = BlogPost(title=title, content=content)
db.session.add(post)
db.session.commit()
hex_token = secret.token_hex(8) # new line
post.save_thumbnail(hex_token)
db.session.close()
return redirect(url_for('blog.index'))
form = BlogPostForm()
return render_template('add_blog.html', form=form)
这行得通,但是我想知道为什么我的初始版本表现得如此
答案 0 :(得分:0)
因为您的类BlogPost和属性hex_token仅被声明一次。
hex_token = db.Column(db.String(16), nullable=False, default=secrets.token_hex(8))
定义hex_token时,默认值仅定义一次,并且作为默认选项存储在表设置中。每次调用该类的方法时,都不能动态更改默认值。这就是为什么每次您调用使用hex_token的该类的方法时hex_token返回相同的值的原因。