tjoenz
tjoenz

Reputation: 709

Noobie with no understanding of formsets

I have an instance where I am creating an order form with multiple models. I want these models to be rendered in one form and was told that formsets are my answer. I have been doing research how this works and still spinning my wheels not knowing. Sorry if this is simple and I'm not seeing it.

Here are my models:

class Contact(models.Model):
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)
    email_address = models.EmailField(max_length=275)
    address = models.CharField(max_length=10, choices=ADDRESS_CHOICES)

    def __unicode__(self):
        return "%s %s" % (self.first_name, self.last_name)


class BaseStationary(models.Model):
    contact = models.ForeignKey(Contact, related_name='%(class)s_related')
    address = models.CharField(max_length=10, choices=ADDRESS_CHOICES)
    quantity = models.CharField(max_length=3, choices=QUANTITY_CHOICES)

    class Meta:
        abstract = True


class LetterHead(BaseStationary):
    pass


class WindowEnv(BaseStationary):
    pass


class NumberTenEnv(BaseStationary):
    pass


class NineByTwelveEnv(BaseStationary):
    pass


class TenByThirteenEnv(BaseStationary):
    pass


class BusinessCard(models.Model):
    contact = models.ForeignKey(Contact, related_name='businesscards')
    card_first_name = models.CharField(max_length=100)
    card_last_name = models.CharField(max_length=100)
    title = models.CharField(max_length=100)
    print_choices = models.CharField(max_length=19, choices=PRINT_CHOICES)
    card_styles = models.CharField(max_length=12, choices=CARD_CHOICES)
    card_email_address = models.EmailField(max_length=275)
    office_phone_number = PhoneNumberField(_('main office phone number'),
        blank=True, null=True)
    toll_free_number = PhoneNumberField(_('toll free number'),
        blank=True, null=True)
    mobile_number = PhoneNumberField(_('mobile phone number'),
        blank=True, null=True)
    fax_number = PhoneNumberField(_('main office fax'),
        blank=True, null=True)
    card_mailing_address = models.CharField(max_length=10,
        choices=ADDRESS_CHOICES)
    card_quantity = models.CharField(max_length=3,
        choices=CARD_QUANTITY_CHOICES)


class RushOrder(models.Model):
    contact = models.ForeignKey(Contact, related_name='rushorders')
    rush_order = models.BooleanField()
    in_hand_date = models.DateField(blank=True, null=True)


class OrderNote(models.Model):
    contact = models.ForeignKey(Contact, related_name='ordernotes')
    add_note = models.BooleanField()
    notes = models.TextField()

Here are my forms:

class ContactForm(forms.ModelForm):
    address = forms.ChoiceField(required = True, widget=RadioSelect(), choices=ADDRESS_CHOICES)
    class Meta:
        model = Contact


class LetterHeadForm(forms.ModelForm):
    address = forms.ChoiceField(required = True, widget=RadioSelect(attrs={'id': 'letterhead_address', 'required': 'True'}), choices=ADDRESS_CHOICES)
    class Meta:
        model = LetterHead
        widgets = {
            'contact': forms.HiddenInput,
            'quantity': forms.Select(attrs={'id': 'letterhead_quantity'}, choices=QUANTITY_CHOICES),
        }


class WindowEnvForm(forms.ModelForm):
    address = forms.ChoiceField(required = True, widget=RadioSelect(attrs={'id': 'windowenv_address', 'required': 'True'}), choices=ADDRESS_CHOICES)
    class Meta:
        model = WindowEnv
        widgets = {
            'contact': forms.HiddenInput,
            'quantity': forms.Select(attrs={'id': 'windowenv_quantity'}, choices=QUANTITY_CHOICES),
        }


class NumberTenEnvForm(forms.ModelForm):
    address = forms.ChoiceField(required = True, widget=RadioSelect(attrs={'id': 'numbertenenv_address', 'required': 'True'}), choices=ADDRESS_CHOICES)
    class Meta:
        model = NumberTenEnv
        widgets = {
            'contact': forms.HiddenInput,
            'quantity': forms.Select(attrs={'id': 'numbertenenv_quantity'}, choices=QUANTITY_CHOICES),
        }


class NineByTwelveEnvForm(forms.ModelForm):
    address = forms.ChoiceField(required = True, widget=RadioSelect(attrs={'id': 'ninebytwelveenv_address', 'required': 'True'}), choices=ADDRESS_CHOICES)
    class Meta:
        model = NineByTwelveEnv
        widgets = {
            'contact': forms.HiddenInput,
            'quantity': forms.Select(attrs={'id': 'ninebytwelveenv_quantity'}, choices=QUANTITY_CHOICES),
        }


class TenByThirteenEnvForm(forms.ModelForm):
     address = forms.ChoiceField(required = True, widget=RadioSelect(attrs={'id': 'tenbythirteenenv_address', 'required': 'True'}), choices=ADDRESS_CHOICES)
    class Meta:
        model = TenByThirteenEnv
        widgets = {
            'contact': forms.HiddenInput,
            'quantity': forms.Select(attrs={'id': 'tenbythirteenenv_quantity'}, choices=QUANTITY_CHOICES),
        }


class BusinessCardForm(forms.ModelForm):
    print_choices = forms.ChoiceField(required = True, widget=RadioSelect(), choices=PRINT_CHOICES)
    card_styles = forms.ChoiceField(required = True, widget=RadioSelect(), choices=CARD_CHOICES)
    card_mailing_address = forms.ChoiceField(required = True, widget=RadioSelect(), choices=ADDRESS_CHOICES)
    class Meta:
        model = BusinessCard
        widgets = {
            'contact': forms.HiddenInput,
        }


class RushOrderForm(forms.ModelForm):
    class Meta:
        model = RushOrder
        widgets = {
            'contact': forms.HiddenInput,
            'rush_order': forms.CheckboxInput,
            'in_hand_date': forms.extras.SelectDateWidget
        }


class OrderNoteForm(forms.ModelForm):
    class Meta:
        model = OrderNote
        widgets = {
            'contact': forms.HiddenInput,
            'add_note': forms.CheckboxInput,
            'notes': forms.Textarea
        }

And here is my view:

class OrderFormView(CreateView):
    model = Contact
    form_class = ContactForm
    template_name = 'orderform.html'
    success_url = 'success'

def get_context_data(self, **kwargs):
    context = super(OrderFormView, self).get_context_data(**kwargs)
    context.update({
        'letterhead_form': LetterHeadForm,
        'windowenv_form': WindowEnvForm,
        'numbertenenv_form': NumberTenEnvForm,
        'ninebytwelveenv_form': NineByTwelveEnvForm,
        'tenbythirteenenv_form': TenByThirteenEnvForm,
        'businesscard_form': BusinessCardForm,
        'rushorder_form': RushOrderForm,
        'ordernote_form': OrderNoteForm,
        })
    return context

def form_valid(self, form):
    if form.is_valid():
        data = form.cleaned_data
        email = OrderFormNotification(to=[settings.ORDERFORM_EMAIL_ADDRESS, ],
                extra_context=data)
        email.send()

Thanks in advance for any insight. Even if it's to point me in the direction to better understand formsets for this.

Upvotes: 0

Views: 97

Answers (1)

Mark Lavin
Mark Lavin

Reputation: 25164

If you need 9 forms for 9 different models then I don't believe formsets will help you. Formsets are for constructing multiple forms of the same type. Likewise the CreateView is intended to be used only in the simple case of creating a single model. If you are creating multiple models/validating multiple forms you will find yourself fighting with CreateView to make this work. You would be better off writing your own view class built from ProcessFormView perhaps even View.

Upvotes: 1

Related Questions