My form field looks something like the following:
class FooForm(ModelForm):
somefield = models.CharField(
widget=forms.TextInput(attrs={'readonly':'readonly'})
)
class Meta:
model = Foo
Geting an error like the following with the code above: init() got an unexpected keyword argument 'widget'
I thought this is a legitimate use of a form widget?
Setting readonly on a widget only makes the input in the browser read-only. Adding a clean_sku which returns instance. sku ensures the field value will not change on form level. This way you can use model's (unmodified save) and avoid getting the field required error.
A widget is Django's representation of an HTML input element. The widget handles the rendering of the HTML, and the extraction of data from a GET/POST dictionary that corresponds to the widget. The HTML generated by the built-in widgets uses HTML5 syntax, targeting <!
The is_valid() method is used to perform validation for each field of the form, it is defined in Django Form class. It returns True if data is valid and place all data into a cleaned_data attribute.
You should use a form field and not a model field:
somefield = models.CharField(
widget=forms.TextInput(attrs={'readonly': 'readonly'})
)
replaced with
somefield = forms.CharField(
widget=forms.TextInput(attrs={'readonly': 'readonly'})
)
Should fix it.
Note that the readonly
attribute does not keep Django from processing any value sent by the client. If it is important to you that the value doesn't change, no matter how creative your users are with FireBug, you need to use a more involved method, e.g. a ReadOnlyField
/ReadOnlyWidget
like demonstrated in a blog entry by Alex Gaynor.
I was going into the same problem so I created a Mixin that seems to work for my use cases.
class ReadOnlyFieldsMixin(object):
readonly_fields =()
def __init__(self, *args, **kwargs):
super(ReadOnlyFieldsMixin, self).__init__(*args, **kwargs)
for field in (field for name, field in self.fields.iteritems() if name in self.readonly_fields):
field.widget.attrs['disabled'] = 'true'
field.required = False
def clean(self):
cleaned_data = super(ReadOnlyFieldsMixin,self).clean()
for field in self.readonly_fields:
cleaned_data[field] = getattr(self.instance, field)
return cleaned_data
Usage, just define which ones must be read only:
class MyFormWithReadOnlyFields(ReadOnlyFieldsMixin, MyForm):
readonly_fields = ('field1', 'field2', 'fieldx')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With