我有一个WTForms自定义验证函数,它返回一个包含散列的变量:
def dupe_check(self, field):
"""
Check for duplicate images.
"""
def get_hash():
"""
Get hash of image.
"""
f = field.data
img = Image.open(f)
imghash = imagehash.dhash(img)
f.seek(0)
return imghash
imghash = str(get_hash())
hashcheck = str(Sights.query.filter(Sights.image_hash == imghash).first())
if hashcheck == imghash:
raise ValidationError('Duplicate image detected!')
class AddImageForm(FlaskForm):
sights_image = FileField('image', validators=[FileRequired(), FileAllowed(images, 'Images only!'), dupe_check])
将位于imghash
的{{1}}变量公开给位于forms.py
的Flask视图的最佳方法是什么?
views.py
应该进入WTForms HiddenField吗?我应该创建会话变量吗?我应该将imghash
函数转换为类吗?
我的目标是在Flask视图期间将哈希写入数据库,但不必重新生成哈希,因为它已在验证期间创建。
答案 0 :(得分:0)
在这种情况下,您可以将函数get_hash()
转换为表单类的方法:
class AddImageForm(FlaskForm):
sights_image = FileField('image', validators=[...])
def get_hash(self):
f = self.sights_image.data
img = Image.open(f)
imghash = imagehash.dhash(img)
f.seek(0)
return imghash
然后在视图功能中,您只需使用表单调用它,例如:
from flask import request
@app.route('/', methods=['GET', 'POST'])
def test():
form = AddImageForm()
if request.method == 'POST':
hash = form.get_hash()
答案 1 :(得分:0)
在dupe_check(self, field)
self
中是表单实例,因此您可以将计算出的哈希值存储在表单中,并在以后的处理中使用它。
这是一个自包含的示例,请注意我创建了一个类验证器,而不是使用一个简单的方法。
from flask import Flask, request, flash, render_template_string, redirect
from flask_wtf import FlaskForm
from wtforms import ValidationError, StringField
app = Flask(__name__)
app.config['SECRET_KEY'] = '0123456789'
def get_hash(data):
# Use data to compute hash
image_hash = 1000000
return image_hash
class HashValidator(object):
def __init__(self, message=None):
if not message:
message = u'Duplicate image detected!'
self.message = message
def __call__(self, form, field):
# Pass field data to hash function
_img_hash = get_hash(field.data)
# Store the hash in the form
form.imghash = _img_hash
# calculate if existing hash exists
# hashcheck = str(Sights.query.filter(Sights.image_hash == _img_hash).first())
hashcheck = 1000000
if hashcheck == _img_hash:
raise ValidationError(self.message)
class AddImageForm(FlaskForm):
# sights_image = FileField('image', validators=[HashValidator()])
# Use an Stringfield to make the sample easier
sights_image = StringField('image', validators=[HashValidator()])
_template = '''
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul class=flashes>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
<form action="/" method="POST">
{{form.csrf_token}}
{{form.sights_image}}
{% if form.sights_image.errors %}
<ul>{% for error in form.sights_image.errors %}<li>{{ error }}</li>{% endfor %}</ul>
{% endif %}
<button type='submit'>Submit</button>
</form>
'''
@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
_image_form = AddImageForm()
if _image_form.validate_on_submit():
flash("Validated: get_hash returned {}".format(_image_form.imghash))
return redirect('/')
else:
# didn't validate template will show error
flash("Error. get_hash returned {}".format(_image_form.imghash))
return render_template_string(_template, form=_image_form)
else:
_image_form = AddImageForm()
return render_template_string(_template, form=_image_form)
if __name__ == '__main__':
app.run(port=9876, debug=True)