#21596: Add method to formset to add a form -----------------------------+-------------------------------------- Reporter: nickname123 | Owner: nobody Type: New feature | Status: new Component: Forms | Version: 1.6 Severity: Normal | Resolution: Keywords: | Triage Stage: Unreviewed Has patch: 0 | Needs documentation: 0 Needs tests: 0 | Patch needs improvement: 0 Easy pickings: 0 | UI/UX: 0 -----------------------------+--------------------------------------
Comment (by nickname123): I will elaborate. Sorry for the confusing description. Right now, there is no easy way to add a form to a formset that I could find documented. The formset api doesn't have anything to assist with this internally that I could find either. My use case is similar to the django admin where a user can click "add another". The formset documentation suggests that this should be done client side by javascript: https://docs.djangoproject.com/en/dev/topics/forms/formsets/#empty-form I think this should be possible to implement server side. This is a simple mixin that demonstrates my intentions: {{{ class AddableFormSet(BaseModelFormSet): can_add_form = True def add_form(self, **kwargs): if self.is_valid(): # add the form tfc = self.total_form_count() form = self._construct_form(tfc, **kwargs) form.is_bound = False self.forms.append(form) # make data mutable self.data = self.data.copy() # increase hidden form counts total_count_name = '%s-%s' % (self.management_form.prefix, TOTAL_FORM_COUNT) self.data[total_count_name] = self.management_form.cleaned_data[TOTAL_FORM_COUNT] + 1 @property def add_form_key(self): return self.add_prefix(ADD_FORM_KEY) }}} Now, it is easy to hook up in the view: {{{ class CustomWizard(NamedUrlSessionWizardView): def get_form(self, step=None, data=None, files=None): # could be a form or formset formish = super(CustomWizard, self).get_form(step=step, data=data, files=files) # support adding forms to formsets if there is post data if data: if isinstance(formish, BaseModelFormSet) and formish.can_add_form: if formset.add_form_key in data: formset.add_form() }}} Now, in the template you just need something like this: {{{ {{ formset.management_form }} {% for form in formset %} {{ form }} {% endfor %} {% if formset.can_add_form %} <hr /> <input name="{{ formset.add_form_key }}" type="submit" value="Add another" /> <hr /> {% endif %} }}} This really makes the formset more useful to me. It is simple to implement and now doesn't require javascript to implement the "add another" button. It took me a pretty long time to figure out the internals to implement this so I doubt someone new to the framework would be able to. This seems like a logical addition to the formset api. (aside: I chose to require is_valid() in the add_form() method because it would be frustrating for the user to create 15 forms to find out they are all invalid. The way I have implemented it supports multiple formsets on the same page. Which is important for my use case that mixes individual forms and formsets in a "form container") It is fairly straightforward and I think that any formset used for data entry could make use of this. So I think it would be useful to almost anyone using a formset. -- Ticket URL: <https://code.djangoproject.com/ticket/21596#comment:2> Django <https://code.djangoproject.com/> The Web framework for perfectionists with deadlines. -- You received this message because you are subscribed to the Google Groups "Django updates" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-updates+unsubscr...@googlegroups.com. To post to this group, send email to django-updates@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-updates/069.22d397bef71da190c3f70540a1c370e7%40djangoproject.com. For more options, visit https://groups.google.com/groups/opt_out.