Python中生成包含验证码的表单字段的实现方式
在Python中,生成包含验证码的表单字段,可以使用Python的第三方库来实现。其中,常用的库包括Flask-WTF和django.forms。
首先,我们来看一下使用Flask-WTF库生成包含验证码的表单字段的示例代码。
from flask import Flask, render_template, request
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired, Length, ValidationError
from flask_wtf.file import FileField, FileRequired, FileAllowed
from flask_uploads import UploadSet, IMAGES
import random
from PIL import Image, ImageDraw, ImageFont
from io import BytesIO
app = Flask(__name__)
app.config['SECRET_KEY'] = 'your_secret_key'
photos = UploadSet('photos', IMAGES)
class MyForm(FlaskForm):
name = StringField('Name', validators=[DataRequired(), Length(min=2, max=20)])
photo = FileField('Photo', validators=[FileRequired(), FileAllowed(photos, 'Images only!')])
submit = SubmitField('Submit')
@app.route('/', methods=['GET', 'POST'])
def index():
form = MyForm()
if form.validate_on_submit():
# 验证码校验
if 'captcha' in session and request.form['captcha'].lower() == session['captcha'].lower():
# 验证码正确
# 其他处理逻辑
pass
else:
form.captcha.errors.append('Invalid captcha!')
return render_template('index.html', form=form)
@app.route('/captcha')
def captcha():
# 生成验证码
captcha_text = ''.join(random.sample('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', 4))
# 将验证码图片绘制到Image对象中
captcha_image = Image.new('RGB', (100, 30), (255, 255, 255))
captcha_font = ImageFont.truetype('arial.ttf', 20)
captcha_draw = ImageDraw.Draw(captcha_image)
captcha_draw.text((10, 5), captcha_text, font=captcha_font, fill=(0, 0, 0))
# 将验证码图片保存到BytesIO对象中
captcha_io = BytesIO()
captcha_image.save(captcha_io, 'JPEG', quality=70)
captcha_io.seek(0)
# 将验证码保存到session中
session['captcha'] = captcha_text
# 返回验证码图片
return send_file(captcha_io, mimetype='image/jpeg')
if __name__ == '__main__':
app.run()
上述示例中,首先定义了一个继承自FlaskForm的表单类MyForm,其中包含了两个字段:name和photo。name字段是一个文本输入字段,photo字段是一个文件上传字段。
在表单提交的时候,通过form.validate_on_submit()方法进行验证,同时进行验证码的校验:获取用户输入的验证码,并与之前生成的验证码进行比对。验证码的生成可以在/captcha路由下进行,使用PIL库生成一个随机的验证码,并将验证码图片保存在BytesIO对象中。
此外,为了支持文件上传功能,在Flask中使用了Flask-Uploads来处理文件上传。上述示例中,定义了一个photos的上传集合,并在photo字段的验证中限制了文件类型只能是图片。
下面我们再来看一下使用django.forms库生成包含验证码的表单字段的示例代码。
from django import forms
from PIL import Image, ImageDraw, ImageFont
import random
from io import BytesIO
class MyForm(forms.Form):
name = forms.CharField(label='Name', max_length=20, widget=forms.TextInput(attrs={'class': 'form-control'}))
photo = forms.ImageField(label='Photo', widget=forms.ClearableFileInput(attrs={'class': 'form-control-file'}))
captcha = forms.CharField(label='Captcha', max_length=4, widget=forms.TextInput(attrs={'class': 'form-control'}))
def validate_captcha(self):
if self.cleaned_data['captcha'].lower() != self.request.session.get('captcha', '').lower():
raise forms.ValidationError('Invalid captcha!')
def captcha(request):
# 生成验证码
captcha_text = ''.join(random.sample('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', 4))
# 将验证码图片绘制到Image对象中
captcha_image = Image.new('RGB', (100, 30), (255, 255, 255))
captcha_font = ImageFont.truetype('arial.ttf', 20)
captcha_draw = ImageDraw.Draw(captcha_image)
captcha_draw.text((10, 5), captcha_text, font=captcha_font, fill=(0, 0, 0))
# 将验证码图片保存到BytesIO对象中
captcha_io = BytesIO()
captcha_image.save(captcha_io, 'JPEG', quality=70)
captcha_io.seek(0)
# 将验证码保存到session中
request.session['captcha'] = captcha_text
# 返回验证码图片
return HttpResponse(captcha_io.getvalue(), content_type='image/jpeg')
在上述示例中,首先定义了一个继承自forms.Form的表单类MyForm,其中包含了三个字段:name、photo和captcha。name字段是一个文本输入字段,photo字段是一个文件上传字段,captcha字段是一个文本输入字段用于输入验证码。
在表单验证时,通过validate_captcha方法进行验证码的校验,如果验证码不匹配,将抛出ValidationError异常。为了获取用户输入的验证码和之前生成的验证码进行比对,需要在视图函数中将request对象传递给表单。
验证码的生成和保存在session中的过程与Flask中的实现类似。
以上就是使用Flask-WTF和django.forms在Python中生成包含验证码的表单字段的实现方式的示例代码。两种方式的核心是生成验证码图片,并将验证码保存在session中,以便在表单验证时进行比对。根据具体的框架和需求,可以选择适合的方式来实现验证码功能。
