34

Django does not respect the max_length attribute of TextField model field while validating a ModelForm.

So I define a LimitedTextField inherited from the models.TextField and added validation bits similar to models.CharField:

from django.core import validators

class LimitedTextField(models.TextField):
    def __init__(self, *args, **kwargs):
        super(LimitedTextField, self).__init__(*args, **kwargs)
        self.max_length = kwargs.get('max_length')
        if self.max_length:
            self.validators.append(validators.MaxLengthValidator(self.max_length))

    def formfield(self, **kwargs):
        defaults = {'max_length': self.max_length}
        defaults.update(kwargs)
        return super(LimitedTextField, self).formfield(**defaults)

But this still has no affect on ModelForm validation.

What am I missing?

Braiam
  • 1
  • 11
  • 47
  • 78
onurmatik
  • 5,105
  • 7
  • 42
  • 67

3 Answers3

84

As of Django 1.2 this can be done by validators at model level, as explained here: https://docs.djangoproject.com/en/stable/ref/validators/

from django.core.validators import MaxLengthValidator

class Comment(models.Model):
    comment = models.TextField(validators=[MaxLengthValidator(200)])

Since Django 1.7, you can use max_length which is only enforced in client side. See here

chhantyal
  • 11,874
  • 7
  • 51
  • 77
onurmatik
  • 5,105
  • 7
  • 42
  • 67
12

You can enforce a max length for a TextField by defining a CharField with a Textarea widget like this:

class MyClass(models.Model):
    textfield = models.TextField()

class MyForm(forms.ModelForm):
    textfield = forms.CharField(
        max_length = 50,
        widget = forms.Textarea
    )

    class Meta:
        model = MyClass
        fields = ('textfield',)
Michael Godshall
  • 880
  • 11
  • 18
  • 1
    but then i should repeat this for every text field that i want to limit. it would be much better if nothing other then specifying max_length is required. – onurmatik Jul 09 '10 at 06:52
  • 1
    Yes, specifying max_length in the model would be a little easier, but the solution I offered is the standard approach you will find in many django apps, and even within django itself (see django.contrib.comments). I have yet to see the custom TextField you are describing. Good luck. – Michael Godshall Jul 09 '10 at 07:47
0

No need to import MaxLengthValidator from validators for Django 2.x

from django.db import models
class Comment(models.Model):
  comment = models.TextField(max_length=200)
Wariored
  • 1,303
  • 14
  • 25
  • It's always better to add some explanation to the answer. ;) – DaFois Jun 08 '18 at 10:59
  • 2
    From the doc: If you specify a max_length attribute, it will be reflected in the Textarea widget of the auto-generated form field. However it is NOT ENFORCED at the model or database level. – Daviddd Feb 27 '19 at 07:51