PhoebeB
PhoebeB

Reputation: 8570

Change form fields based on request

The application has a category field that may be set in the session and may not. If it is, I don't want to see the field on the form just have it as a hidden field with the value equal to that in the request. If it's not set then I want to display a dropdown.

I've setup the form to include the dropdown, which is the default for this field and my question is, where is the best place to change the widget to hidden, bearing in mind I need the request so I can't do it in the forms init, which is the obvious place.

Tried this approach, but the field remained visible:

class DocForm(forms.ModelForm):


    class Meta:
        model = Document
        fields = __all__
        widgets = {"creator": forms.HiddenInput(),}

    def __init__(self, *args, **kwargs):
        #cant do it here because don't have request

class DocAddView(CreateView):


    form_class = DocForm


    def get_form_class(self):
        form_class = super(DocAddView, self).get_form_class()
        form_class.Meta.widgets['category'] = forms.HiddenInput()
        return form_class

Upvotes: 4

Views: 803

Answers (1)

Alasdair
Alasdair

Reputation: 309089

Change your form's __init__ method to take the request object.

class DocForm(forms.ModelForm):
    ...
    def __init__(self, request, *args, **kwargs):
        super(DocForm, self).__init__(*args, **kwargs)
        use_hidden_input = do_something_with_request(request)
        if use_hidden_input:
            self.fields['category'].widget = forms.HiddenInput()

Then override get_form_kwargs, so that the view passes the request to the form.

class DocAddView(CreateView):
    ...
    def get_form_kwargs(self):
        # grab the current set of form #kwargs
        kwargs = super(DocAddView, self).get_form_kwargs()
        # Update the kwargs with the user_id
        kwargs['request'] = self.request
        return kwargs

This approach is explained in this blog post.

Upvotes: 6

Related Questions