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.
-
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 ofRegistrationForm
):{{ 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.
ModelFormField
¶
-
class
django_superform.fields.
ModelFormField
(form_class, kwargs=None, **field_kwargs)[source]¶ This class is the to
FormField
what Django’sModelForm
is toForm
. It has the same behaviour asFormField
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 ofUser
model and it will also save theEmailForm
and therefore create an instance ofEmailAddress
!However you usually want to use one of the exsting subclasses, like
ForeignKeyFormField
or extend fromModelFormField
class and override theget_instance()
method.Note
Usually the
ModelFormField
is used inside aSuperModelForm
. You actually can use it within aSuperForm
, but since this form type does not have asave()
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 thisModelFormField
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 byget_instance()
. Theempty_permitted
kwarg will be set to the inverse of therequired
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’ssave()
method. But only ifshall_save()
returnsTrue
.
-
shall_save
(form, name, composite_form)[source]¶ Return
True
if the givencomposite_form
(the nested form of this field) shall be saved. ReturnFalse
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 theempty_permitted
argument for the form was set toTrue
. That way you can allow empty forms.
-
ForeignKeyFormField
¶
FormSetField
¶
ModelFormSetField
¶
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 fromBaseInlineFormSet
or was created by theinlineformset_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 theinlineformset_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)