如何将上载文件字段添加到Wagtail表单中? [英] How can I add an Upload File field to a Wagtail Form?

查看:73
本文介绍了如何将上载文件字段添加到Wagtail表单中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使文件上载成为表单页面上可能的Wagtail表单字段类型。如何配置模型以实现此目的?请注意,我对允许用户上传PDF之类的文档文件而不是图像更感兴趣。

解决方案

这是很棒的文章。下面的代码直接从文章中获取(但是如果有文章,请在此处复制),但是,您可能希望按照该文章逐步解释所有内容。



此刻涉及到很多事情,您需要:


  1. 扩展 AbstractFormField 定义新的字段类型。

  2. 扩展 FormBuilder 以处理新的字段类型。

  3. 在您的FormPage上将 form_builder 设置为自定义的 FormBuilder 类。

  4. 覆盖FormPage上的 serve 方法,将文件数据传递到表单(仅当您使用Wagtail 1.12及以下版本时,因为它会自动从 W 1.13

  5. 覆盖 process_form_submission 处理文件

这是完整的代码:



从wagtail.wagtailforms.models导入AbstractFormField,FORM_FIELD_CHOICES
从wagtail.wagtailforms.forms导入FormBuilder
从wagtail.wagtailimages.fields导入WagtailImageField


def filename_to_title(文件名):
从os.path导入splitext
如果文件名:
结果= splitext(文件名)[0]
结果= result.replace('-','').replace('_','')
返回result.title()


类FormField(AbstractFormField):
FORM_FIELD_CHOICES = list(FORM_FIELD_CHOICES)+ [('image','Upload Image')]
field_type = models.CharField(
verbose_name = _('field type'),
max_length = 16,
选择= FORM_FIELD_CHOICES)
页面= ParentalKey('FormPage',related_name ='form_fields')


class ExtendedFormBuilder(FormBuilder):
def create_image_upload_field(self,field,options):
return WagtailImageField(** options)
FIELD_TYPES = FormBuilder.FIELD_TYPES
FIELD_TYPES.update({
'image':create_image_upload_field,
})


class FormPage(AbstractEmailForm):
form_builder = ExtendedFormBuilder

def serve(self,request,* args,** kwargs):
if request.method =='POST':
#form = self .get_form(request.POST,page = self,user = request.user)#原始行
form = self.get_form(request.POST,request.FILES,page = self,user = request.user)

if form.is_valid():
self.process_form_submission(form)
return render(
request,
self.get_landing_page_template(request),
self.get_context(request)

else:
的形式= self.get_form(page = self,user = request.user)

context = self。 get_context(request)
context ['for m'] =表单
return render(
request,
self.get_template(request),
context


def process_form_submission(自我,形式):
cleaned_data = form.cleaned_data

for name,form.fields.iteritems():
if isinstance(field,WagtailImageField):
image_file_data = cleaned_data [name]
如果image_file_data:
ImageModel = get_image_model()
image = ImageModel(
file = cleaned_data [name],
title = filename_to_title( cleaned_data [name] .name),
collection = self.upload_image_to_collection,
#假设总有一个用户-将会失败,否则
upload_by_user = form.user,

image.save()
cleaned_data.update({name:image.id})
else:
#从数据中删除值
del cleaned_data [name]

form_data = json。 dumps(cleaned_data,cls = DjangoJSONEncoder)
submitt_object = dict(
页面=自我,
form_data = form_data,
用户= form.user,


简介= RichTextField(空白=真实)
Thank_you_text = RichTextField(空白=真实)

FormPage.content_panels = [
FieldPanel('title',classname = 完整标题),
FieldPanel('intro',classname = full),
InlinePanel('form_fields',label = Form字段),
FieldPanel('thank_you_text' ,classname = full),
MultiFieldPanel([
FieldRowPanel([
FieldPanel('from_address',classname = col6)),
FieldPanel('to_address',classname = col6),
]),
FieldPanel('subject'),
],电子邮件),
]

以下是(未试用的)代码,用于处理文档而不是图像:

  from django.forms从wagtail.wagtaildocs.models导入FileField 
导入get_document_model
#其他导入

类FormField(AbstractFormField):
FORM_FIELD_CHOICES = list(FORM_FIELD_CHOICES)+ [ ('document','Upload Document')]
#`field_type`和`page`保持不变


类ExtendedFormBuilder(FormBuilder):
def create_document_upload_field( self,field,options):
return FileField(** options)
FIELD_TYPES = FormBuilder.FIELD_TYPES
FIELD_TYPES.update({
'document':create_document_upload_field,
})

类FormPage(AbstractEmailForm):
# form_builder属性和 serve保持不变。

def process_form_submission(self,form):
cleaned_data = form.cleaned_data

for name,form.fields.iteritems()中的字段:
如果isinstance(field,FileField):
document_file_data = cleaned_data [name]
if document_file_data:
DocumentModel = get_document_model()
document = DocumentModel(
file = cleaned_data [ name],
title = filename_to_title(cleaned_data [name] .name),
#假设总有一个用户-将会失败,否则
upload_by_user = form.user,

document.save()
cleaned_data.update({name:document.id})
else:
#从数据中删除值
del cleaned_data [name]

#The r函数的其余部分不变


I want to make File Upload a possible Wagtail Form field type on form pages. How do I configure the models to make this possible? Please note I am more interested in allowing users to upload document files like PDFs rather than images.

解决方案

Here is a great article from LB Johnson on that matter. The code below is directly taken from the article (but copying here in case the article goes away), however you might want to follow the article as it explains everything step by step.

It's quite involved at the moment, you'll need to:

  1. extend AbstractFormField to define a new field type.
  2. extend FormBuilder to deal with the new field type.
  3. set form_builder to your custom FormBuilder class on your FormPage .
  4. override the serve method on the FormPage to pass the file data to the form (only if you use Wagtail 1.12 and below as it does it automatically from Wagtail 1.13)
  5. override the process_form_submission to process the file

Here is the full code:

from wagtail.wagtailforms.models import AbstractFormField, FORM_FIELD_CHOICES
from wagtail.wagtailforms.forms import FormBuilder
from wagtail.wagtailimages.fields import WagtailImageField


def filename_to_title(filename):
    from os.path import splitext
    if filename:
        result = splitext(filename)[0]
        result = result.replace('-', ' ').replace('_', ' ')
        return result.title()


class FormField(AbstractFormField):
    FORM_FIELD_CHOICES = list(FORM_FIELD_CHOICES) + [('image', 'Upload Image')]
    field_type = models.CharField(
        verbose_name=_('field type'),
        max_length=16,
        choices=FORM_FIELD_CHOICES)
    page = ParentalKey('FormPage', related_name='form_fields')


class ExtendedFormBuilder(FormBuilder):
    def create_image_upload_field(self, field, options):
        return WagtailImageField(**options)
    FIELD_TYPES = FormBuilder.FIELD_TYPES
    FIELD_TYPES.update({
        'image': create_image_upload_field,
    })


class FormPage(AbstractEmailForm):
    form_builder = ExtendedFormBuilder

    def serve(self, request, *args, **kwargs):
        if request.method == 'POST':
            # form = self.get_form(request.POST, page=self, user=request.user)  # Original line
            form = self.get_form(request.POST, request.FILES, page=self, user=request.user)

            if form.is_valid():
                self.process_form_submission(form)
                return render(
                    request,
                    self.get_landing_page_template(request),
                    self.get_context(request)
                )
        else:
            form = self.get_form(page=self, user=request.user)

        context = self.get_context(request)
        context['form'] = form
        return render(
            request,
            self.get_template(request),
            context
        )

    def process_form_submission(self, form):
        cleaned_data = form.cleaned_data

        for name, field in form.fields.iteritems():
            if isinstance(field, WagtailImageField):
                image_file_data = cleaned_data[name]
                if image_file_data:
                    ImageModel = get_image_model()
                    image = ImageModel(
                        file=cleaned_data[name],
                        title=filename_to_title(cleaned_data[name].name),
                        collection=self.upload_image_to_collection,
                        # assumes there is always a user - will fail otherwise
                        uploaded_by_user=form.user,
                        )
                    image.save()
                    cleaned_data.update({name: image.id})
                else:
                    # remove the value from the data
                    del cleaned_data[name]

        form_data = json.dumps(cleaned_data, cls=DjangoJSONEncoder)
        submission_object = dict(
            page=self,
            form_data=form_data,
            user=form.user,
        )

    intro = RichTextField(blank=True)
    thank_you_text = RichTextField(blank=True)

    FormPage.content_panels = [
        FieldPanel('title', classname="full title"),
        FieldPanel('intro', classname="full"),
        InlinePanel('form_fields', label="Form fields"),
        FieldPanel('thank_you_text', classname="full"),
        MultiFieldPanel([
            FieldRowPanel([
                FieldPanel('from_address', classname="col6"),
                FieldPanel('to_address', classname="col6"),
            ]),
            FieldPanel('subject'),
        ], "Email"),
]

Here is the (untested) code to handle a document instead of an image:

from django.forms import FileField
from wagtail.wagtaildocs.models import get_document_model
# Other imports

class FormField(AbstractFormField):
    FORM_FIELD_CHOICES = list(FORM_FIELD_CHOICES) + [('document', 'Upload Document')]
    # `field_type` and `page` remain unchanged


class ExtendedFormBuilder(FormBuilder):
    def create_document_upload_field(self, field, options):
        return FileField(**options)
    FIELD_TYPES = FormBuilder.FIELD_TYPES
    FIELD_TYPES.update({
        'document': create_document_upload_field,
    })

class FormPage(AbstractEmailForm):
    # `form_builder` attribute and `serve` remain unchanged.

    def process_form_submission(self, form):
        cleaned_data = form.cleaned_data

        for name, field in form.fields.iteritems():
            if isinstance(field, FileField):
                document_file_data = cleaned_data[name]
                if document_file_data:
                    DocumentModel = get_document_model()
                    document = DocumentModel(
                        file=cleaned_data[name],
                        title=filename_to_title(cleaned_data[name].name),
                        # assumes there is always a user - will fail otherwise
                        uploaded_by_user=form.user,
                    )
                    document.save()
                    cleaned_data.update({name: document.id})
                else:
                    # remove the value from the data
                    del cleaned_data[name]

        # The rest of the function is unchanged

这篇关于如何将上载文件字段添加到Wagtail表单中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆