TextField maximum number of characters

In models.py I have the following class:

class Page(models.Model):
    node = models.OneToOneField()
    content = models.TextField()

In forms.py I have the following class:

class PageForm(ModelForm):
    class Meta:
        model = models.Page
        fields = (
            'content',
        )
        widgets = {
            'content': Textarea(attrs={'class': 'textarea form-control tiny-editor',}),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.use_required_attribute = False

Based on a variable (stored in the class Account) I want to set a maximum number of characters for the TextField.

First question is what is the best way to make the variable available to all views. Second question is what is the best place to set the maximum number of characters in forms.py or views.py

Kind regards,

Johanna

First, just to make sure we’re clear here - setting a max size on the TextField only affects the maximum size of the textarea widget on the page. Django does not enforce any size limit on a TextField in the database. (Documented at Model field reference | Django documentation | Django)

I am assuming that Account is related to your User model by a 1-1 relationship, and that the instance you want to use is the instance associated with the currently logged in account.

If all these assumptions are true, then this is something you would generally address in your view.

You have access to the logged-in user as request.user and so your max_field_size may be accessed as request.user.account.max_field_size.

After the form is created, you can then adjust that attribute on the widget in the form.

It’s going to look something like:

page_form = PageForm()
page_form.fields['content'].widget.attrs['maxlength'] = max_field_size

(The specifics will likely vary based upon the implementation of your views.)

Hi Ken,

Thanks fro your reply. I tried this in my view:

It adds the maxlength attribute to the textarea but doesn’t prevent me from entering a text with more characters then maxlength.

When I add max_length to the model:

content = models.TextField(max_length=1024)

It adds the same attribute to the textarea, but in this case validation works.

I have no idea why, I hope you do.

Are you making the same change to the form in the POST processing of that form? (Not just on the GET) That’s where the validation would be occurring.
That would be the only difference I can think of right off-hand between those two situations.

I think it’s a TinyMCE issue, it simply ignores the maxlength attribute. I edited the tinymce.init() function:

tinymce.init({
  selector: 'textarea.tiny-editor',
  plugins: 'visualchars wordcount',
  setup: function(editor) {
    var max = 1024;
    editor.on('submit', function(event) {
      var numChars = tinymce.activeEditor.plugins.wordcount.body.getCharacterCount();
      if (numChars > max) {
        alert("Ensure this value has at most " + max + " characters (it has " + numChars + " )");
	event.preventDefault();
	return false;
      }
    });
  }
});

This works, what I need to figure out is, how to set var max = 1024;

Ok, I had no idea TinyMCE was involved.

The appropriate way to do this:

  • Add max_field_size to your context.

  • Somewhere in your template, use the json_script filter to output the desired max value:
    {{ max_field_size|json_script:max-field-size }}
    (The “max-field-size” is the id of the data element being added to the page.)

  • Change your setup function for the max attribute to be:
    var max = JSON.parse(document.getElementById('max-field-size').textContent);

This is the preferred, secure, recommended mechanism for adding values in your template to be accessed by JavaScript within the page.

Hi Ken,

Thanks for bearing with me.

I realise this is a very common use case which Django solves very elegantly. Thanks for pointing it out to me.

Kind regards,

Johanna