2017-12-21 19 views
1

フォームページにWagtailフォームのフィールドタイプをアップロードできるようにします。これを可能にするためにモデルを設定するにはどうすればよいですか?ご注意ください私は、ユーザーが画像ではなくPDFのような文書ファイルをアップロードできるようにすることに興味があります。Upload FileフィールドをWagtailフォームに追加するにはどうすればよいですか?

答えて

3

ここにLB Johnsonのgreat articleがあります。下のコードは記事から直接取り上げられています(ただし、記事がなくなるとここにコピーします)。

それは現時点ではかなり複雑だ、あなたがする必要があります:新しいフィールドタイプを定義するためにAbstractFormFieldを拡張

  1. FormBuilderを拡張して新しいフィールドタイプを処理します。
  2. form_builderをカスタムFormBuilderクラスに設定してください。
  3. オーバーライドFormPage上serveメソッドは、フォームにファイルデータを渡すために(あなたはセキレイ1.12を使用している場合にのみ、以下のことがWagtail 1.13から自動的にそれをしないよう)ファイルを処理するために
  4. オーバーライドprocess_form_submission
ここ

は完全なコードである:ここ

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"), 
] 

ではなく、画像の文書を処理する(未テスト)コードである:

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 
+0

ありがとうございます!しかし、ユーザーがPDFをアップロードできるようにしたいのであれば、画像の代わりに文書をアップロードするのはどうでしょうか? – NVN

+0

申し訳ありませんが、私は画像の代わりに文書を求める質問の部分を見逃しました。つまり、手順は同じです。私はあなた自身の上でコードを微調整しようとし、すべてがどのように連携しているかを理解することを本当にお勧めします。私はあなたが立ち往生した場合の例を追加しましたが、私はそれをテストする時間がありませんでした。 –

関連する問題