Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django: How can I modify a form field's value before it's rendered but after the form has been initialized?

Given a form, I want to change a value on a field before it gets rendered. This is what I'm trying:

class RequiredFormSet(BaseFormSet):
    def add_form(self):
        tfc = self.total_form_count()
        self.forms.append(self._construct_form(tfc))
        if self.is_bound:
            data = self.management_form.data.copy() # make data mutable
            data[TOTAL_FORM_COUNT] = self.management_form.cleaned_data[TOTAL_FORM_COUNT] + 1
            self.management_form.data = data
        else:
            self.extra += 1

I thought everything was stored in data, but I guess that data has been passed off to the individual fields (or widgets) already? So what property do I need to modify exactly?

like image 439
mpen Avatar asked Nov 15 '22 03:11

mpen


1 Answers

I hope this helps:

This is the method which creates forms in a BaseFormSet:

def _construct_form(self, i, **kwargs):
    """
    Instantiates and returns the i-th form instance in a formset.
    """
    defaults = {'auto_id': self.auto_id, 'prefix': self.add_prefix(i)}
    if self.is_bound:
        defaults['data'] = self.data
        defaults['files'] = self.files
    if self.initial:
        try:
            defaults['initial'] = self.initial[i]
        except IndexError:
            pass
    # Allow extra forms to be empty.
    if i >= self.initial_form_count():
        defaults['empty_permitted'] = True
    defaults.update(kwargs)
    form = self.form(**defaults)
    self.add_fields(form, i)
    return form

As you can see there's an attribute called 'self.initial', this is passed as initial data to the new created form. If you want to use _construct_form to add a new form and set custom initial data you should modify 'self.initial' before calling _construct_form. Initial must be a dictionary where the key is the field name and the value the value you want for your field.

like image 98
Nate Gentile Avatar answered Jan 12 '23 05:01

Nate Gentile