Fields

This is the class hierachy of all the available composite fields to be used in a SuperForm:

+ CompositeField
|
+-+ FormField
| |
| +-+ ModelFormField
|   |
|   +-- ForeignKeyFormField
|
+-+ FormSetField
  |
  +-+ ModelFormSetField
    |
    +-+ InlineFormSetField

CompositeField

class django_superform.fields.CompositeField(*args, **kwargs)[source]

Implements the base structure that is relevant for all composite fields. This field cannot be used directly, use a subclass of it.

get_initial(form, name)[source]

Get the initial data that got passed into the superform for this composite field. It should return None if no initial values where given.

get_kwargs(form, name)[source]

Return the keyword arguments that are used to instantiate the formset.

get_prefix(form, name)[source]

Return the prefix that is used for the formset.

FormField

class django_superform.fields.FormField(form_class, kwargs=None, **field_kwargs)[source]

A field that can be used to nest a form inside another form:

from django import forms
from django_superform import SuperForm

class AddressForm(forms.Form):
    street = forms.CharField()
    city = forms.CharField()

class RegistrationForm(SuperForm):
    first_name = forms.CharField()
    last_name = forms.CharField()
    address = FormField(AddressForm)

You can then display the fields in the template with (given that registration_form is an instance of RegistrationForm):

{{ registration_form.address.street }}
{{ registration_form.address.street.errors }}
{{ registration_form.address.city }}
{{ registration_form.address.city.errors }}

The fields will all have a prefix in their name so that the naming does not clash with other fields on the page. The name attribute of the input tag for the street field in this example will be: form-address-street. The name will change if you set a prefix on the superform:

form = RegistrationForm(prefix='registration')

Then the field name will be registration-form-address-street.

You can pass the kwargs argument to the __init__ method in order to give keyword arguments that you want to pass through to the form when it is instaniated. So you could use this to pass in initial values:

class RegistrationForm(SuperForm):
    address = FormField(AddressForm, kwargs={
        'initial': {'street': 'Stairway to Heaven 1'}
    })

But you can also use nested initial values which you pass into the superform:

RegistrationForm(initial={
    'address': {'street': 'Highway to Hell 666'}
})

The first method (using kwargs) will take precedence.

get_form(form, name)[source]

Get an instance of the form.

get_form_class(form, name)[source]

Return the form class that will be used for instantiation in get_form. You can override this method in subclasses to change the behaviour of the given form class.

ModelFormField

class django_superform.fields.ModelFormField(form_class, kwargs=None, **field_kwargs)[source]

This class is the to FormField what Django’s ModelForm is to Form. It has the same behaviour as FormField but will also save the nested form if the super form is saved. Here is an example:

from django_superform import ModelFormField

class EmailForm(forms.ModelForm):
    class Meta:
        model = EmailAddress
        fields = ('email',)

class UserForm(SuperModelForm):
    email = ModelFormField(EmailForm)

    class Meta:
        model = User
        fields = ('username',)

user_form = UserForm(
    {'username': 'john', 'form-email-email': 'john@example.com'})
if user_form.is_valid():
    user_form.save()

This will save the user_form and create a new instance of User model and it will also save the EmailForm and therefore create an instance of EmailAddress!

However you usually want to use one of the exsting subclasses, like ForeignKeyFormField or extend from ModelFormField class and override the get_instance() method.

Note

Usually the ModelFormField is used inside a SuperModelForm. You actually can use it within a SuperForm, but since this form type does not have a save() method, you will need to take care of saving the nested model form yourself.

get_instance(form, name)[source]

Provide an instance that shall be used when instantiating the modelform. The form argument is the super-form instance that this ModelFormField is used in. name is the name of this field on the super-form.

This returns None by default. So you usually want to override this method in a subclass.

get_kwargs(form, name)[source]

Return the keyword arguments that are used to instantiate the formset.

The instance kwarg will be set to the value returned by get_instance(). The empty_permitted kwarg will be set to the inverse of the required argument passed into the constructor of this field.

save(form, name, composite_form, commit)[source]

This method is called by django_superform.forms.SuperModelForm.save() in order to save the modelform that this field takes care of and calls on the nested form’s save() method. But only if shall_save() returns True.

shall_save(form, name, composite_form)[source]

Return True if the given composite_form (the nested form of this field) shall be saved. Return False if the form shall not be saved together with the super-form.

By default it will return False if the form was not changed and the empty_permitted argument for the form was set to True. That way you can allow empty forms.

ForeignKeyFormField

class django_superform.fields.ForeignKeyFormField(form_class, kwargs=None, field_name=None, blank=None, **field_kwargs)[source]

FormSetField

class django_superform.fields.FormSetField(formset_class, kwargs=None, **field_kwargs)[source]

First argument is a formset class that is instantiated by this FormSetField.

You can pass the kwargs argument to specify kwargs values that are used when the formset_class is instantiated.

ModelFormSetField

class django_superform.fields.ModelFormSetField(formset_class, kwargs=None, **field_kwargs)[source]

InlineFormSetField

class django_superform.fields.InlineFormSetField(parent_model=None, model=None, formset_class=None, kwargs=None, **factory_kwargs)[source]

The InlineFormSetField helps when you want to use a inline formset.

You can pass in either the keyword argument formset_class which is a ready to use formset that inherits from BaseInlineFormSet or was created by the inlineformset_factory.

The other option is to provide the arguments that you would usually pass into the inlineformset_factory. The required arguments for that are:

model
The model class which should be represented by the forms in the formset.
parent_model
The parent model is the one that is referenced by the model in a foreignkey.
form (optional)
The model form that is used as a baseclass for the forms in the inline formset.

You can use the kwargs keyword argument to pass extra arguments for the formset that are passed through when the formset is instantiated.

All other not mentioned keyword arguments, like extra, max_num etc. will be passed directly to the inlineformset_factory.

Example:

class Gallery(models.Model):
name = models.CharField(max_length=50)
class Image(models.Model):
gallery = models.ForeignKey(Gallery) image = models.ImageField(...)
class GalleryForm(ModelFormWithFormSets):
class Meta:
model = Gallery fields = (‘name’,)
images = InlineFormSetField(
parent_model=Gallery, model=Image, extra=1)