How to use Django Formset in Formwizard

287 Views Asked by At

I have created a from wizard with 3 steps forms, on this second step I have a using a Formset which is dynamically updating. I am able to get the step1 & step2 data in the form list done() method but Formset(ProductAttributeFormset) data is not getting. How can I process the ProductAttributeFormset data?

My Form as follows:

from django.db.models import fields
from django import forms
from django.forms import formset_factory
from django.db.models.fields import CharField
from .models import Product,Category,Attribute,ProductAtribute

class createProductForm(forms.ModelForm):
    title = forms.CharField(label = ("Product Name"),required=True)
    category = forms.ModelChoiceField(queryset=Category.objects.filter(status=True),required=True,widget=forms.Select(attrs={'class': ''}))
    class Meta:
        model = Product
        labels = {
            "product_image": "Image"
        }
        widgets = {
            'product_image': forms.FileInput(),
        }
        fields = ['title','product_slug','in_stock','category','product_image','description']

class createSEOForm(forms.ModelForm):
    class Meta:
        model = Product
        fields = ['meta_title','meta_keyword','meta_description']

class createAttributeForm(forms.ModelForm):
    class Meta:
        model = Attribute
        fields = ['name']

class createProductAttributeForm(forms.ModelForm,forms.Form):
    class Meta:
        model = ProductAtribute
        widgets = {
            'image': forms.FileInput(),
        }
        fields = ['image','sku','price','offer_price','attribute','attribute_value']

ProductAttributeFormset = formset_factory(createProductAttributeForm, extra=2)

My view file as follows:

from django.shortcuts import render
from formtools.wizard.views import SessionWizardView
# Create your views here.
from django.shortcuts import redirect, render
from django.http import HttpResponseRedirect
from django.http import HttpResponse
from django.contrib import messages
from .models import Attribute, Product, ProductAtribute
from .forms import createProductForm,createAttributeForm,createProductAttributeForm,createSEOForm,ProductAttributeFormset
from django.contrib.auth.decorators import login_required
from django.core.files.storage import FileSystemStorage
from django.conf import settings,os
from django.forms.models import construct_instance
# Create your views here.
FORMS = [("0", createProductForm),
         ("1", createProductAttributeForm),("2", createSEOForm)]

TEMPLATES = {0: "products/step1.html",1: "products/step2-formset.html",2: "products/step3.html"}
class createProductWizard(SessionWizardView):
    file_storage = FileSystemStorage(location=os.path.join(settings.MEDIA_ROOT, 'tmp'))
    form_list = FORMS
    form_dict = dict(form_list)
    def get_template_names(self):
         return TEMPLATES[int(self.steps.current)]

    def get_context_data(self, form, **kwargs):
        context = super(createProductWizard, self).get_context_data(form=form, **kwargs)
        if self.steps.current == '1':
            context.update({
                'formset': ProductAttributeFormset
            })
        return context
         
    def get_form_initial(self, step):
        if 'id' in self.kwargs and (step == '0' or step == '2'):
            product_id = self.kwargs['id']
            data = Product.objects.get(id=product_id)
            from django.forms.models import model_to_dict
            project_dict = model_to_dict(data)
            return project_dict
        elif 'id' in self.kwargs and step == '1': 
            product_id = self.kwargs['id']
            data = ProductAtribute.objects.get(product_id=product_id)
            from django.forms.models import model_to_dict
            project_dict = model_to_dict(data)
            return project_dict
        else:
            return self.initial_dict.get(step, {})

    def done(self,form_list,**kwargs):
        try:
            if self.kwargs['id']:
                product_instance=Product.objects.get(id=self.kwargs['id'])
                product_attribute_instance = ProductAtribute.objects.get(product_id=self.kwargs['id'])
            else:
                product_instance = Product()

        except Exception as e:    
            product_instance = Product()

           
        for form in form_list:
            product_instance = construct_instance(form, product_instance, form._meta.fields, form._meta.exclude)
        
        product_instance.save()
        

        return redirect('list')
0

There are 0 best solutions below