Dean Lauder
Dean Lauder

Reputation: 51

Changing Django form property 'required' by bool in template

I'm trying to have the option for an admin to make fields required or not for a user.

My form looks like this.

class StudentDetailForm(MyForm):
    first_name = fields.CharField(required=True)
    last_name = fields.CharField(required=True)
    date_of_birth = MyDateField(required=True, widget=MyDateInput(attrs{'class': 'dobpicker'}))
    id_number2 = fields.CharField(required=True, label='PPS Number')
    note = fields.CharField(required=False,
          widget=forms.Textarea(attrs={'cols': '25', 'rows': '2'}))


class Meta:
    model = Person
    fields = ['first_name', 'last_name', 'date_of_birth', 'id_number2', 'gender', 'note']

etc...

This is how I tried to changed the required field. It loops through all the fields and presents tick boxes for visible or required on the admin page.

Then each is presented on the form page with a required or not value.

student_form = StudentDetailForm(None, data=request.POST or None)
mother_form = ParentDetailForm(None, data=request.POST or None, prefix='g1', instance=mother)
father_form = ParentDetailForm(None, data=request.POST or None, prefix='g2', instance=father)
family_form = FamilyDetailForm(None, data=request.POST or None)

# student_form, mother_form, father_form, family_form = get_web_intake_forms(school, request.POST or None, requestpps)

for name, value in webfields.items():
    if not value['visible']:
        # name is actual name plus : plus a number
        # split up to name and number
        bits = name.split(':')
        fname = bits[0]
        formnum = bits[1]
        if formnum == '1':
            del student_form.fields[fname]
        elif formnum == '2':
            del mother_form.fields[fname]
        elif formnum == '3':
            del father_form.fields[fname]
        elif formnum == '4':
            del family_form.fields[fname]

    elif value['required']:
        # name is actual name plus : plus a number
        # split up to name and number
        bits = name.split(':')
        fname = bits[0]
        formnum = bits[1]
        if formnum == '1':
            student_form.base_fields[fname].required = True
        elif formnum == '2':
            mother_form.fields[fname].required = True
        elif formnum == '3':
            father_form.fields[fname].required = True
        elif formnum == '4':
            family_form.base_fields[fname].required = True

    elif not value['required']:
        # name is actual name plus : plus a number
        # split up to name and number
        bits = name.split(':')
        fname = bits[0]
        formnum = bits[1]
        if formnum == '1':
            student_form.base_fields[fname].required = False
        elif formnum == '2':
            mother_form.fields[fname].required = False
        elif formnum == '3':
            father_form.fields[fname].required = False
        elif formnum == '4':
            family_form.base_fields[fname].required = False

I tried base_fields which kind of worked but was a bit messy.

Any ideas?

Upvotes: 0

Views: 69

Answers (1)

Alasdair
Alasdair

Reputation: 309089

You probably don't want to change base_fields - that updates the fields of the StudentDetailForm class, not just the particular form instance

Depending on the rest of your view, setting form.fields['first_name'].required should work.

However, it's normally better to set self.fields['first_name'].required inside the form's __init__ method. I'm not sure how you would do this because you seem to have multiple forms and many field names, so here's a simpler example.

class MyForm(forms.Form):
    first_name = forms.CharField()

    def __init__(self, *args, **kwargs):
        first_name_required = kwargs.pop('first_name_required')
        super(MyForm, self).__init__(*args, **kwargs)
        self.fields['first_name'].required = first_name_required

You would then initialise your form like:

form = MyForm(data=request.POST, first_name_required=True)

Upvotes: 1

Related Questions