Django Form Wizard not saving FileField
NickName:Samoht Ask DateTime:2021-11-30T22:34:47

Django Form Wizard not saving FileField

I have a 5 step form wizard, each their own form. I have a FileField in the first, but something is going wrong. When I reach the final step and press submit, my model gets saved but the file field is empty in my database. It's not "null", but actually empty. I created the "file_storage" variable but that only stores the file temporarily, it get's deleted as soon as I submit the form

this is my wizard 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:
 ...

models.py:

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

No errors, no warning messages. I'm lost...

Copyright Notice:Content Author:「Samoht」,Reproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/70171081/django-form-wizard-not-saving-filefield

Answers
Samoht 2021-12-01T13:08:46

found out that in form_data_sets = [form.cleaned_data for form in form_list]\nthe file is actually located in there. So I just did:\nfile = {'kvk_file': form_data_sets[0].get('kvk_file')}\nform_data2.update(file)\nand now it works!",


More about “Django Form Wizard not saving FileField” related questions

Django Form Wizard not saving FileField

I have a 5 step form wizard, each their own form. I have a FileField in the first, but something is going wrong. When I reach the final step and press submit, my model gets saved but the file field...

Show Detail

Forcing steps with django form wizard

How would I force steps for the django form wizard? I have step 0 showing a Subscription page with different account types. I wanted to have the ability to send someone a link such as /join/basi...

Show Detail

Keeping Original Filename for FileField in Django

I would like to keep the original file name of an UploadedFile in Django that has its location stored in a FileField. Right now I am observing that if two files have the same name, the first file

Show Detail

Initialize Django Form FileField

I have a Django form class like; class FileDefinitionForm(ModelForm): fileContent = forms.FileField(required=False) def __init__(self, *args, **kwargs): super(FileDefinitionForm, ...

Show Detail

Django Form Wizard With Fieldsets

I'm using the Django Form Wizard (From 1.8 located in formtools) to split a form into multiple steps. This works fine and all. But I'm interested in making fieldsets in my form and splitting my form

Show Detail

Saving Django Wizard: not quite magical

Can anyone help me figure out how to save my django FormWizard? I have searched and read the docs for days, but cannot figure out why my wizard will not save. Form: from django.contrib.formtools.

Show Detail

Django: Using the FileField

I want to make a application when the user upload the file, so get it to system, and execute the linux command like "xxd". cSite---cSite---settings.py | |__etc... | --myapp...

Show Detail

Django form wizard handling

I am having a bit of a problem understanding the django form wizard. Mainly, I don't understand how to handle the form_list. This is my view thus far: class AddLocation(SessionWizardView):

Show Detail

Unit Testing a Django Form with a FileField

I have a form like: #forms.py from django import forms class MyForm(forms.Form): title = forms.CharField() file = forms.FileField() #tests.py from django.test import TestCase from forms ...

Show Detail

Setting up Django Form Wizard

I'm attempting to set up a Django Form Wizard, but I'm having trouble getting it to work. I've followed the example, from the Django website, but can't get anything to work. When I go to the URL that

Show Detail