Model Field Types Overview
A tour of common model fields including CharField, TextField, IntegerField, DecimalField, DateField, DateTimeField, BooleanField, and how choices, defaults, null, and blank interact with each field type.
1. Introduction
Every field in a Django model maps to a column in the database. Choosing the right field type matters — it affects what data is valid, how the database stores it, how forms render it, and how the admin displays it.
This guide covers the field types you will use in almost every project: text, numeric, date and time, boolean, and how to configure defaults, null, and blank correctly for each.
- You should already have the
Pagemodel created in the previous tutorial. - Your
.venvmust be active and Django 5.2 installed.
2. Text fields
CharField
Use CharField for short text — titles, names, slugs, email addresses. Always requires max_length.
title = models.CharField(max_length=200)
slug = models.SlugField(max_length=220, unique=True)
email = models.EmailField() # max_length=254 by default
TextField
Use TextField for long text with no length limit — blog posts, descriptions, comments. Do not use max_length on TextField — it has no effect on the database, only on form widgets.
content = models.TextField()
bio = models.TextField(blank=True)
Other text variants
url = models.URLField() # validates as a URL, max_length=200
ip = models.GenericIPAddressField() # stores IPv4 or IPv6 addresses
3. Numeric fields
IntegerField and variants
quantity = models.IntegerField()
sort_order = models.PositiveIntegerField(default=0)
score = models.SmallIntegerField() # -32768 to 32767
views = models.PositiveSmallIntegerField() # 0 to 32767
FloatField vs DecimalField
Use FloatField for approximate values where precision is not critical — ratings, percentages. Use DecimalField for money and anything where exact precision matters. DecimalField requires max_digits and decimal_places.
rating = models.FloatField() # approximate, e.g. 4.75
price = models.DecimalField(max_digits=10, decimal_places=2)
# max_digits=10, decimal_places=2 allows up to 99999999.99
DecimalField for currency values.
4. Date and time fields
published_date = models.DateField()
start_time = models.TimeField()
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
scheduled = models.DateTimeField(null=True, blank=True)
DateField— stores a date only. Maps toDATEin the database.TimeField— stores a time only. Maps toTIMEin the database.DateTimeField— stores both date and time. The most commonly used of the three.auto_now_add=True— sets the value once when the record is first created. Cannot be changed afterward.auto_now=True— updates the value every time the record is saved. Useful for tracking when a record was last modified.
USE_TZ = True in settings, Django stores all datetimes in UTC and converts to your TIME_ZONE setting for display. Always keep USE_TZ = True — it prevents subtle bugs when users are in different time zones.
5. Boolean fields
is_active = models.BooleanField(default=True)
is_published = models.BooleanField(default=False)
is_verified = models.BooleanField(default=False)
BooleanField stores True or False. Always provide a default — without one, the database column has no default value and Django will raise an error when creating records without explicitly setting the field.
If you need to allow a third state — unknown or not yet set — use null=True on a BooleanField. This replaces the old NullBooleanField which was removed in Django 4.0.
consent_given = models.BooleanField(null=True, default=None)
# Can be True, False, or None (unknown)
6. null and blank — what is the difference
This is one of the most common points of confusion in Django. They sound similar but do completely different things:
null=True— tells the database to allowNULLin the column. A database-level setting.blank=True— tells Django forms and validation that this field is not required. A form-level setting.
The rules are straightforward once you understand the separation:
# Required in both forms and database
title = models.CharField(max_length=200)
# Optional in forms, stores empty string in database (correct for text fields)
subtitle = models.CharField(max_length=200, blank=True)
# Optional in forms, stores NULL in database (correct for non-text fields)
published_at = models.DateTimeField(null=True, blank=True)
# Wrong — avoid null=True on CharField and TextField
# Django stores empty strings for text, not NULL
bad_example = models.CharField(max_length=200, null=True) # avoid this
CharField, TextField), use blank=True only — not null=True. For everything else (DateTimeField, ForeignKey, IntegerField), use both null=True, blank=True together when the field is optional.
7. Setting defaults
Use default to set a value that is used automatically when none is provided:
status = models.CharField(max_length=20, default='draft')
sort_order = models.PositiveIntegerField(default=0)
is_active = models.BooleanField(default=True)
views = models.PositiveIntegerField(default=0)
You can also use a callable as a default — a function that returns a value. This is useful for dynamic defaults like the current time:
from django.utils import timezone
expires_at = models.DateTimeField(default=timezone.now)
timezone.now, not timezone.now(). Passing it with parentheses calls it once at class definition time and uses the same fixed value for every record. Without parentheses, Django calls it fresh each time a record is created.
8. Putting it together
Here is a realistic model that uses a variety of field types with the right options:
# pages/models.py
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=200)
slug = models.SlugField(max_length=220, unique=True)
content = models.TextField()
excerpt = models.CharField(max_length=300, blank=True)
views = models.PositiveIntegerField(default=0)
is_published = models.BooleanField(default=False)
published_at = models.DateTimeField(null=True, blank=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
9. Next steps
You now know the most common field types and how to configure them correctly. The next step covers file and image fields — a special category that requires extra setup for handling user uploads.