Wagtail中将图片保存至模型的方法及'BoundField'无width属性错误解决
解决Wagtail中保存图片到模型时的'BoundField'无'width'属性错误
问题根源
- 直接通过
review_form['author']、review_form['file']获取的是BoundField对象,并非表单提交的实际值,Wagtail创建Image时需要真实文件对象,而非字段对象,这直接触发了'BoundField' object has no attribute 'width'错误。 - 表单处理时未传入
request.FILES(文件上传必须依赖该参数),也未先验证表单有效性。 - 普通Model没有
is_valid()方法,调用new_review.is_valid()属于错误用法。
修正方案
1. 修复表单处理逻辑
调整serve方法,确保传入文件参数、验证表单、从cleaned_data取真实值:
class FeedbackPage(Page): ... def serve(self, request): review_form_class = ReviewForm if "review" in request.POST: # 文件上传必须传入request.FILES review_form = review_form_class(request.POST, request.FILES, prefix='review') # 先验证表单有效性 if review_form.is_valid(): new_review = Reviews() # 从cleaned_data获取实际提交值 new_review.author = review_form.cleaned_data['author'] new_review.is_pub = False new_review.text = review_form.cleaned_data['text'] # 用验证后的文件对象创建Wagtail Image new_image = Image.objects.create( file=review_form.cleaned_data['file'], title="Image title" ) new_review.image = new_image # 直接保存模型实例 new_review.save() else: # GET请求初始化空表单 review_form = review_form_class(prefix='review') # 返回页面响应(示例) return render(request, self.template, { 'page': self, 'review_form': review_form, })
2. 优化表单继承(可选)
TemplateForm多用于Wagtail后台页面配置,前端提交表单建议改用Django基础表单类:
from django import forms class ReviewForm(forms.Form): author = forms.CharField() text = forms.CharField(widget=forms.Textarea) file = forms.ImageField(required=False)
3. 补充Image创建的必填字段(可选)
若创建Image时提示缺少集合字段,可指定默认根集合:
from wagtail.core.models import Collection default_collection = Collection.objects.get(name='Root') new_image = Image.objects.create( file=review_form.cleaned_data['file'], title="Image title", collection=default_collection )
核心注意事项
- 必须通过
form.cleaned_data获取验证后的真实数据,禁止直接操作form['field']。 - 处理文件上传的表单,实例化时必须传入
request.FILES。 - 表单处理流程必须先执行
is_valid(),再进行数据写入。 - 普通Django Model无
is_valid()方法,直接调用save()即可完成存储。
内容的提问来源于stack exchange,提问作者Mr. ksen
相关产品推荐
相关产品推荐

