繁体   English   中英

Django 表单向导不保存 FileField

[英]Django Form Wizard not saving FileField

我有一个 5 步表单向导,每个都有自己的表单。 我首先有一个 FileField,但是出了点问题。 当我到达最后一步并按下提交时,我的 model 被保存,但我的数据库中的文件字段为空。 它不是“空”,而是实际上是空的。 我创建了“file_storage”变量,但它只临时存储文件,一旦我提交表单,它就会被删除

这是我的向导 class:

import json
import logging
import os

import keyboard
from django.conf import settings
from django.core.files.storage import FileSystemStorage
from django.core.mail import EmailMessage
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render
from formtools.wizard.views import SessionWizardView

from .forms import *

logger = logging.getLogger('django')

FORMS = [
    ("company", CompanyForm),
    ("addresses", AddressesForm),
    ("references", ReferenceFormSet),
    ("contacts", ContactFormSet),
    ("payment", PaymentForm),

]

TEMPLATES = {
    "company":    "form/step-1.html",
    "addresses":  "form/step-2.html",
    "references": "form/step-3.html",
    "contacts":   "form/step-4.html",
    "payment":    "form/step-5.html",

}

form_data = []
form_data2 = {}

class RegisterWizard(SessionWizardView):
file_storage = FileSystemStorage(location=os.path.join(settings.MEDIA_ROOT, 'temp'))

def get_context_data(self, form, **kwargs):
    context = super().get_context_data(form=form, **kwargs)
    context.update({'callme_forms': CallMeForms(prefix='callme')})

    return context

@property
def first_step_files(self):
    return self.storage.get_step_files(self.steps.first)

def process_step(self, form):
    data = {}
    form_data.extend(self.get_form_step_data(form))
    for attr, value in self.get_form_step_data(form).items():
        if 'reference' not in attr:
            if 'company-' in attr:
                attr = attr.replace('company-', '')
            if 'addresses-' in attr:
                attr = attr.replace('addresses-', '')
            if 'payment-' in attr:
                attr = attr.replace('payment-', '')
            if 'document-' in attr:
                attr = attr.replace('document-', '')
            if value == 'on':
                value = True
            if value == 'off':
                value = False

            data[attr] = value if value else data.get(attr)

        if 'reference' not in attr or 'contact' not in attr:
            try:
                form_data2.update(data)
            except e:
                logger.error(e)
    return self.get_form_step_data(form)

def get_template_names(self):
    return [TEMPLATES[self.steps.current]]

def render_goto_step(self, *args, **kwargs):
    form = self.get_form(data=self.request.POST, files=self.request.FILES)
    self.storage.set_step_data(self.steps.current, self.process_step(form))
    self.storage.set_step_files(self.steps.first, self.process_step_files(form))

    return super().render_goto_step(*args, **kwargs)

def done(self, form_list, **kwargs):
    data = {}
    data2 = {}

    form_data2.pop('csrfmiddlewaretoken')
    form_data2.pop('register_wizard-current_step')

    try:
        data2.update(form_data2)

        for k, v in form_data2.items():
            if 'reference' in k:
                data2.pop(k)
            if 'contact' in k:
                data2.pop(k)

        form_data2.clear()
        form_data2.update(data2)

        form_data2.pop('wizard_goto_step')

        if 'using_mail_address' in form_data2:
            form_data2.pop('using_mail_address')
        if 'different_invoice_address' in form_data2:
            form_data2.pop('different_invoice_address')
        else:
            data['invoice_street'] = form_data2.get('delivery_street')
            data['invoice_zip'] = form_data2.get('delivery_zip')
            data['invoice_city'] = form_data2.get('delivery_city')
            data['invoice_house_number'] = form_data2.get('delivery_number')
            form_data2.update(data)

        form_data2.pop('toa')
        instance = Customer()
        customer = Customer.objects.create(**form_data2)

        form_data_sets = [form.cleaned_data for form in form_list]

        for form in form_list[2].save(commit=False):
            form.customer_id = customer.id
            form.save()

        for form in form_list[3].save(commit=False):
            form.customer_id = customer.id
            form.save()

        form_data2.clear()
        kwargs.clear()
        Customer.objects.all().none()
    except e:
        logger.error(e)
    finally:
        return HttpResponseRedirect('/thank-you')`

forms.py:

class CompanyForm(ModelForm):
 ...
 file = forms.FileField(
    label=_("Choose File"),
    widget=forms.ClearableFileInput(attrs={'class': 'form-control right', 'placeholder': 'choose a file'}),
    required=False,
)
 class Meta:
 ...

模型.py:

class Customer(models.Model):
 ...
 file = models.FileField(
    verbose_name='File',
    upload_to='uploads/',
    null=True
)

没有错误,没有警告消息。 我迷路了...

发现在form_data_sets = [form.cleaned_data for form in form_list]文件实际上位于那里。 所以我只是做了:

file = {'kvk_file': form_data_sets[0].get('kvk_file')}

form_data2.update(file)

现在它可以工作了!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM