• 5
name

A PHP Error was encountered

Severity: Notice

Message: Undefined index: userid

Filename: views/question.php

Line Number: 191

Backtrace:

File: /home/prodcxja/public_html/questions/application/views/question.php
Line: 191
Function: _error_handler

File: /home/prodcxja/public_html/questions/application/controllers/Questions.php
Line: 433
Function: view

File: /home/prodcxja/public_html/questions/index.php
Line: 315
Function: require_once

name Punditsdkoslkdosdkoskdo

Change a Django form field to a hidden field

I have a Django form with a RegexField, which is very similar to a normal text input field.

In my view, under certain conditions I want to hide it from the user, and trying to keep the form as similar as possible. What's the best way to turn this field into a HiddenInput field?

I know I can set attributes on the field with:

form['fieldname'].field.widget.attr['readonly'] = 'readonly'

And I can set the desired initial value with:

form.initial['fieldname'] = 'mydesiredvalue'

However, that won't change the form of the widget.

What's the best / most "django-y" / least "hacky" way to make this field a <input type="hidden"> field?

This may also be useful: {{ form.field.as_hidden }}

  • 195
Reply Report
      • 2
    • This is the best answer IMHO. I've always hated using my "controller" Python code to determine the display of a form field.
      • 2
    • I often make generic form template with crispyforms. If you use crispyforms or you display fields in a simple forloop because you want your form structure in your form class, the widget overriding in the form is the good way to do it. Bu if you manage your form rendering into your template, indeed, this solution is much more clear/clean.
      • 1
    • It's worth noting that this seems to erase any classes you've applied to the field beforehand...

If you have a custom template and view you may exclude the field and use {{ modelform.instance.field }} to get the value.

also you may prefer to use in the view:

form.fields['field_name'].widget = forms.HiddenInput()

but I'm not sure it will protect save method on post.

Hope it helps.

  • 169
Reply Report
    • I end up with a "" is not a valid value for a primary key. in the is_valid method after using this solution.
    • It sounds weird. I think it's related to something else, are you displaying as HiddenInput the primary key of objects you are creating? If yes, you should not.
      • 1
    • on 1.7 use this syntax : hidden_field_name = forms.CharField(label='reset', max_length=256, widget=forms.HiddenInput()) where the key is the newer widget syntax on the end. Tweak for your needs.

an option that worked for me, define the field in the original form as:

forms.CharField(widget = forms.HiddenInput(), required = False)

then when you override it in the new Class it will keep it's place.

  • 59
Reply Report

Firstly, if you don't want the user to modify the data, then it seems cleaner to simply exclude the field. Including it as a hidden field just adds more data to send over the wire and invites a malicious user to modify it when you don't want them to. If you do have a good reason to include the field but hide it, you can pass a keyword arg to the modelform's constructor. Something like this perhaps:

class MyModelForm(forms.ModelForm):
    class Meta:
        model = MyModel
    def __init__(self, *args, **kwargs):
        from django.forms.widgets import HiddenInput
        hide_condition = kwargs.pop('hide_condition',None)
        super(MyModelForm, self).__init__(*args, **kwargs)
        if hide_condition:
            self.fields['fieldname'].widget = HiddenInput()
            # or alternately:  del self.fields['fieldname']  to remove it from the form altogether.

Then in your view:

form = MyModelForm(hide_condition=True)

I prefer this approach to modifying the modelform's internals in the view, but it's a matter of taste.

  • 45
Reply Report
    • just simple tip, kwargs.pop('hide_condition', False) instead of kwargs['hide_condition']. you'll handle the no arg case, have a default and del in the same time.

For normal form you can do

class MyModelForm(forms.ModelForm):
    slug = forms.CharField(widget=forms.HiddenInput())

If you have model form you can do the following

class MyModelForm(forms.ModelForm):
    class Meta:
        model = TagStatus
        fields = ('slug', 'ext')
        widgets = {'slug': forms.HiddenInput()}

You can also override __init__ method

class Myform(forms.Form):
    def __init__(self, *args, **kwargs):
        super(Myform, self).__init__(*args, **kwargs)
        self.fields['slug'].widget = forms.HiddenInput()
  • 22
Reply Report

Trending Tags