Opened 11 years ago
Closed 11 years ago
#22206 closed New feature (fixed)
TextField doesn't set max_length attribute on its formfield, unlike CharField
Reported by: | Chris Wilson | Owned by: | Chris Wilson |
---|---|---|---|
Component: | Forms | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Accepted | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
In django/db/models/fields/init.py, the CharField field type constructs its widgets with a max_length parameter, which ends up in the widget:
class CharField(Field): # django.db.forms.fields def formfield(self, **kwargs): # Passing max_length to forms.CharField means that the value's length # will be validated twice. This is considered acceptable since we want # the value in the form field (to pass into widget for example). defaults = {'max_length': self.max_length} defaults.update(kwargs) return super(CharField, self).formfield(**defaults) class CharField(Field): # django.forms.fields def widget_attrs(self, widget): attrs = super(CharField, self).widget_attrs(widget) if self.max_length is not None and isinstance(widget, TextInput): # The HTML attribute is maxlength, not max_length. attrs.update({'maxlength': str(self.max_length)}) return attrs
But nothing like this happens for the TextField database field, which creates a TextField form field, which uses a Textarea widget by default:
class TextField(Field): description = _("Text") def formfield(self, **kwargs): defaults = {'widget': forms.Textarea} defaults.update(kwargs) return super(TextField, self).formfield(**defaults)
I think that TextField doesn't override form_class, so it gets the default CharField from Field.formfield(), as CharField does, but with a custom widget. So all we'd need to do is set the attribute in the CharField db field:
def formfield(self, **kwargs): # Passing max_length to forms.CharField means that the value's length # will be validated twice. This is considered acceptable since we want # the value in the form field (to pass into widget for example). defaults = {'max_length': self.max_length} defaults.update(kwargs) return super(TextField, self).formfield(**defaults)
and add the attribute to the widget in CharField:
def widget_attrs(self, widget): attrs = super(CharField, self).widget_attrs(widget) if self.max_length is not None: # all types of widgets, not hard coded # The HTML attribute is maxlength, not max_length. attrs.update({'maxlength': str(self.max_length)}) return attrs
Change History (5)
comment:1 by , 11 years ago
Has patch: | set |
---|---|
Owner: | changed from | to
Status: | new → assigned |
comment:2 by , 11 years ago
Triage Stage: | Unreviewed → Accepted |
---|---|
Version: | 1.6 → master |
Sure, maxlength
is now also handled by textarea
in HTML 5 (http://dev.w3.org/html5/markup/textarea.html#textarea.attrs.maxlength).
comment:3 by , 11 years ago
The patch is now in good shape. However, I'd like to add an additional note in the TextField
documentation, something like this:
.. versionchanged:: 1.7 If you specify a ``max_length`` attribute, it will be reflected in the :class:`~django.forms.Textarea` widget of the auto-generated form field. However it is not enforced at the model or database level. Use a :class:`CharField` for that.
Opinion?
comment:5 by , 11 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
https://github.com/django/django/pull/2391