djangovalidationdjango-modelsdjango-formsdjango-2.0

Why should I set max_length when using Choices in a Django model?


In the official Django 2 tutorial I found this:

from django.db import models

class Student(models.Model):
    FRESHMAN = 'FR'
    SOPHOMORE = 'SO'
    JUNIOR = 'JR'
    SENIOR = 'SR'
    YEAR_IN_SCHOOL_CHOICES = (
        (FRESHMAN, 'Freshman'),
        (SOPHOMORE, 'Sophomore'),
        (JUNIOR, 'Junior'),
        (SENIOR, 'Senior'),
    )
    year_in_school = models.CharField(
        max_length=2,
        choices=YEAR_IN_SCHOOL_CHOICES,
        default=FRESHMAN,
    )

Now my question is does using choices mean that only either of the four defined values is valid for this field? If so what is the use of specifying the max_length? If not, why not use a validator that validates if the value is actually exacly one of the specified ones or at least a validator that only accepts an specific length not just an upper bound.


Solution

  • The max_length is enforced at the database level, but the choices are enforced at python code level (when calling full_clean() or clean_<fieldname>()).

    They are independent of each other.

    If you set a value to your field other than the specified choices and you don't call instance.full_clean() or instance.clean_<fieldname>(), it could still get saved to the database without raising errors.

    But if you use djangos forms, the choices validation is done for you (the form calls full_clean()) and you don't need to worry about it.


    This means, for example, if you set max_length smaller than your largest option in choices, your database will silently truncate the values for that field or raise a DatabaseError; either way you will not get it to work.

    This separation is useful, for example, if you want to add more choices later; if the new options are not larger than max_length, there will be no need to to change the database structure (that means, the new migration will NOT issue alter table SQL statements).