Opened 12 years ago
Closed 12 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 , 12 years ago
| Has patch: | set |
|---|---|
| Owner: | changed from to |
| Status: | new → assigned |
comment:2 by , 12 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 , 12 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 , 12 years ago
| Resolution: | → fixed |
|---|---|
| Status: | assigned → closed |
https://github.com/django/django/pull/2391