Django Model Fields Cheat Sheet

Django Model field types and field options

Download as .pdf

API: /api/v1/cheatsheet/django-model-fields-cheat-sheet

Django Model Fields Cheat Sheet

Basic Model Structure

python

1
2
3
4
5
6
7
from django.db import models


class Product(models.Model):
    name = models.CharField(max_length=200)
    price = models.DecimalField(max_digits=8, decimal_places=2)
    is_active = models.BooleanField(default=True)

Basic mapping:

Model class      → Database table
Model field      → Database column
Model instance   → Database row

Text Fields

Field Purpose
CharField Short or limited text
TextField Long text
EmailField Email address
URLField Web address
SlugField URL-friendly text

CharField

Short text with a maximum length:

python

1
name = models.CharField(max_length=200)

Common uses:

  • Names
  • Titles
  • Labels
  • Codes
  • Short descriptions

TextField

Long text:

python

1
description = models.TextField()

Common uses:

  • Articles
  • Comments
  • Biographies
  • Product descriptions
  • Notes

EmailField

Email address:

python

1
email = models.EmailField()

Django validates the value as an email address.

URLField

Web address:

python

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
website = models.URLField()


#### SlugField

URL-friendly text:

slug = models.SlugField()

Example value:

`learning-django-models`

A slug usually contains letters, numbers, hyphens, and underscores.

Make it unique when it identifies a page:

```python
slug = models.SlugField(unique=True)

Number Fields

Field Purpose
IntegerField Whole numbers
PositiveIntegerField Zero or positive whole numbers
SmallIntegerField Smaller whole numbers
BigIntegerField Large whole numbers
FloatField Floating-point numbers
DecimalField Fixed-precision decimal numbers

IntegerField

Whole numbers:

python

1
quantity = models.IntegerField()

Example values:

  • -10
  • 0
  • 25

PositiveIntegerField

Zero or positive whole numbers:

python

1
stock = models.PositiveIntegerField()

Common uses:

  • Stock quantities
  • Page counts
  • View counts
  • Ages

SmallIntegerField

Whole numbers with a smaller database range:

python

1
rating = models.SmallIntegerField()

BigIntegerField

Large whole numbers:

python

1
view_count = models.BigIntegerField()

FloatField

Floating-point number:

python

1
temperature = models.FloatField()

Useful for approximate numeric values.

Do not normally use it for money.

DecimalField

Fixed-precision decimal number:

python

1
2
3
4
price = models.DecimalField(
    max_digits=8,
    decimal_places=2,
)

Options:

  1. max_digits Total number of digits
  2. decimal_places Digits after the decimal point

With the example above:

  • Valid: 123456.78
  • Invalid: 1234567.89

Common uses:

  • Prices
  • Account balances
  • Measurements requiring fixed precision
  • Boolean Fields

BooleanField

Stores True or False:

python

1
is_active = models.BooleanField(default=True)

Common uses:

  • Published or unpublished
  • Active or inactive
  • Enabled or disabled
  • Completed or incomplete

Date and Time Fields

Field Purpose
DateField Date only
TimeField Time only
DateTimeField Date and time
DurationField Length of time

DateField

Stores a date:

python

1
published_on = models.DateField()

Example:

2026-07-24

TimeField

Stores a time:

python

1
opening_time = models.TimeField()

Example:

09:30:00

DateTimeField

Stores a date and time:

python

1
published_at = models.DateTimeField()

Automatically set when the object is created:

python

1
created_at = models.DateTimeField(auto_now_add=True)

Automatically update whenever the object is saved:

python

1
updated_at = models.DateTimeField(auto_now=True)
  • auto_now_add=True Set once during creation
  • auto_now=True Update on every save

DurationField

Stores a period of time:

python

1
running_time = models.DurationField()

Python normally represents the value as a timedelta.

File Fields

Field Purpose
FileField Uploaded files
ImageField Uploaded images

FileField

Stores an uploaded file path:

python

1
document = models.FileField(upload_to="documents/")

Example storage path:

documents/report.pdf

ImageField

Stores an uploaded image path:

python

1
image = models.ImageField(upload_to="images/")

ImageField also validates that the uploaded file is an image.

Pillow is normally required:

python

1
pip install Pillow

Dynamic Upload Paths

bash

1
2
3
4
5
def product_upload_path(instance, filename):
    return f"products/{instance.pk}/{filename}"


image = models.ImageField(upload_to=product_upload_path)

Identifier Fields

Field Purpose
AutoField Auto-incrementing integer
BigAutoField Large auto-incrementing integer
UUIDField UUID identifier

Automatic Primary Key

Django adds a primary key when one is not declared:

python

1
2
class Product(models.Model):
    name = models.CharField(max_length=200)

The model receives an automatic id field.

Access it with:

  • product.id
  • product.pk

UUIDField

Stores a UUID:

python

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import uuid

from django.db import models


class Product(models.Model):
    id = models.UUIDField(
        primary_key=True,
        default=uuid.uuid4,
        editable=False,
    )

Example UUID:

550e8400-e29b-41d4-a716-446655440000

Pass the function itself:

python

1
default=uuid.uuid4

Do not call it:

python

1
default=uuid.uuid4()  # Wrong

Other Useful Fields

Field Purpose
BinaryField Raw binary data
GenericIPAddressField IPv4 or IPv6 address
JSONField JSON-compatible data

GenericIPAddressField

Stores an IP address:

python

1
ip_address = models.GenericIPAddressField()

Possible values:

  • 192.168.1.10
  • 2001:db8::1

JSONField

Stores JSON-compatible data:

python

1
metadata = models.JSONField(default=dict)

Example value:

python

1
2
3
4
{
    "color": "blue",
    "sizes": ["S", "M", "L"],
}

Use a callable for mutable defaults:

json

1
2
metadata = models.JSONField(default=dict)
tags = models.JSONField(default=list)

Do not use a shared object:

python

1
metadata = models.JSONField(default={})  # Avoid

Relationship Fields

Field Relationship
ForeignKey Many-to-one
OneToOneField One-to-one
ManyToManyField Many-to-many

ForeignKey

Many objects relate to one object.

Example:

python

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class Category(models.Model):
    name = models.CharField(max_length=100)


class Product(models.Model):
    name = models.CharField(max_length=200)
    category = models.ForeignKey(
        Category,
        on_delete=models.CASCADE,
    )

Meaning:

  • One category can contain many products.
  • Each product has one category.

Access the category:

python

1
product.category

Access products from a category:

python

1
category.product_set.all()

Add a custom reverse name:

python

1
2
3
4
5
category = models.ForeignKey(
    Category,
    on_delete=models.CASCADE,
    related_name="products",
)

Then use:

python

1
category.products.all()

OneToOneField

One object relates to one object.

python

1
2
3
4
5
6
7
class UserProfile(models.Model):
    user = models.OneToOneField(
        "auth.User",
        on_delete=models.CASCADE,
    )

    biography = models.TextField(blank=True)

Meaning:

  • One user has one profile.
  • One profile belongs to one user.

ManyToManyField

Many objects relate to many objects.

python

1
2
3
4
5
6
7
class Tag(models.Model):
    name = models.CharField(max_length=50)


class Article(models.Model):
    title = models.CharField(max_length=200)
    tags = models.ManyToManyField(Tag)

Meaning:

  • One article can have many tags.
  • One tag can belong to many articles.

Add relationships:

python

1
article.tags.add(tag)

Remove relationships:

python

1
article.tags.remove(tag)

Retrieve related objects:

python

1
article.tags.all()

Optional many-to-many field:

python

1
tags = models.ManyToManyField(Tag, blank=True)

null=True is not used for ManyToManyField.

on_delete Options

Used by ForeignKey and OneToOneField.

Option Behavior
CASCADE Delete related objects
PROTECT Block deletion
RESTRICT Restrict deletion
SET_NULL Set the field to NULL
SET_DEFAULT Set the field to its default
SET(...) Set a custom value
DO_NOTHING Take no automatic action

CASCADE

python

1
2
3
4
category = models.ForeignKey(
    Category,
    on_delete=models.CASCADE,
)

Deleting the category also deletes its products.

PROTECT

python

1
2
3
4
category = models.ForeignKey(
    Category,
    on_delete=models.PROTECT,
)

Django blocks deletion while related products exist.

SET_NULL

python

1
2
3
4
5
category = models.ForeignKey(
    Category,
    on_delete=models.SET_NULL,
    null=True,
)

Deleting the category sets the product’s category to NULL.

null=True is required.

SET_DEFAULT

python

1
2
3
4
5
category = models.ForeignKey(
    Category,
    on_delete=models.SET_DEFAULT,
    default=1,
)

Deleting the category sets the field to its default value.

Common Field Options

Option Purpose
null Allow database NULL
blank Allow an empty value during validation
default Provide a default value
unique Require unique values
choices Restrict allowed values
primary_key Make the field the primary key
db_index Create a database index
editable Include or exclude from forms and admin
help_text Add explanatory text
verbose_name Set a human-readable field name
validators Add validation functions
error_messages Customize validation messages

null

Controls database storage:

python

1
published_at = models.DateTimeField(null=True)
  • null=False Database value is required
  • null=True Database may store NULL

Default:

python

1
null=False

For optional dates:

python

1
2
3
4
published_at = models.DateTimeField(
    null=True,
    blank=True,
)

For optional text, normally use:

python

1
description = models.TextField(blank=True)

Avoid this in most cases:

python

1
2
3
4
description = models.TextField(
    null=True,
    blank=True,
)

Using null=True on text fields creates two empty values:

NULL ""

blank

Controls validation:

python

1
description = models.TextField(blank=True)
  • blank=False Required in forms and validation
  • blank=True May be left empty

Default:

python

1
blank=False

Remember:

null   → Database
blank  → Validation

default

Provides a value when none is supplied:

python

1
2
is_active = models.BooleanField(default=True)
stock = models.PositiveIntegerField(default=0)

Callable default:

python

1
2
3
from django.utils import timezone

created_at = models.DateTimeField(default=timezone.now)

Do not call the function:

python

1
2
default=timezone.now    # Correct
default=timezone.now()  # Usually wrong

Mutable defaults must use callables:

python

1
data = models.JSONField(default=dict)

unique

Requires a unique value:

python

1
email = models.EmailField(unique=True)

Duplicate values are rejected.

Common uses:

  • Usernames
  • Email addresses
  • Slugs
  • Reference numbers
  • External IDs

choices

Limits a field to predefined values:

python

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
STATUS_CHOICES = [
    ("draft", "Draft"),
    ("published", "Published"),
]

status = models.CharField(
    max_length=20,
    choices=STATUS_CHOICES,
    default="draft",
)

Stored value:

draft

Displayed label:

Draft

Get the display label:

python

1
article.get_status_display()

TextChoices

python

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class Article(models.Model):
    class Status(models.TextChoices):
        DRAFT = "draft", "Draft"
        PUBLISHED = "published", "Published"

    status = models.CharField(
        max_length=20,
        choices=Status.choices,
        default=Status.DRAFT,
    )

Use:

python

1
2
Article.Status.DRAFT
Article.Status.PUBLISHED

primary_key

Makes a field the primary key:

python

1
2
3
4
code = models.CharField(
    max_length=20,
    primary_key=True,
)

A primary key is automatically:

  • Unique
  • Required
  • Indexed

Most models can use Django’s automatic primary key.

db_index

Creates a database index:

python

1
2
3
4
sku = models.CharField(
    max_length=50,
    db_index=True,
)

Indexes can improve searches and filtering:

python

1
Product.objects.filter(sku="ABC-123")

Indexes use additional storage and can slow writes.

Use them for fields that are queried frequently.

editable

Controls whether the field appears in model forms and the admin:

python

1
2
3
4
internal_code = models.CharField(
    max_length=50,
    editable=False,
)

help_text

Provides instructions:

python

1
2
3
slug = models.SlugField(
    help_text="Used in the page URL.",
)

The text may appear in forms and the Django admin.

verbose_name

Sets a readable field label:

python

1
2
3
4
created_at = models.DateTimeField(
    "date created",
    auto_now_add=True,
)

Or:

python

1
2
3
4
created_at = models.DateTimeField(
    verbose_name="date created",
    auto_now_add=True,
)

validators

Adds custom validation:

python

1
2
3
4
5
6
from django.core.validators import MinValueValidator


rating = models.IntegerField(
    validators=[MinValueValidator(1)],
)

Multiple validators:

python

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from django.core.validators import (
    MaxValueValidator,
    MinValueValidator,
)


rating = models.IntegerField(
    validators=[
        MinValueValidator(1),
        MaxValueValidator(5),
    ],
)

Field-Specific Options

Option Used with
max_length CharField and similar fields
max_digits DecimalField
decimal_places DecimalField
upload_to FileField and ImageField
auto_now DateField and DateTimeField
auto_now_add DateField and DateTimeField
on_delete ForeignKey and OneToOneField
related_name Relationship fields
to_field ForeignKey and OneToOneField
through ManyToManyField

max_length

Maximum text length:

python

1
title = models.CharField(max_length=200)

Required for CharField.

upload_to

Sets the upload directory:

python

1
2
3
image = models.ImageField(
    upload_to="products/",
)

Date-based path:

pytohn

1
2
3
image = models.ImageField(
    upload_to="products/%Y/%m/",
)

Possible path:

  • products/2026/07/photo.jpg

Sets the reverse relationship name:

python

1
2
3
4
5
6
class Product(models.Model):
    category = models.ForeignKey(
        Category,
        on_delete=models.CASCADE,
        related_name="products",
    )

Reverse query:

python

1
category.products.all()

Without related_name:

python

1
category.product_set.all()

Complete Example

python

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import uuid

from django.db import models


class Category(models.Model):
    name = models.CharField(
        max_length=100,
        unique=True,
    )

    def __str__(self):
        return self.name


class Product(models.Model):
    class Status(models.TextChoices):
        DRAFT = "draft", "Draft"
        ACTIVE = "active", "Active"
        DISCONTINUED = "discontinued", "Discontinued"

    id = models.UUIDField(
        primary_key=True,
        default=uuid.uuid4,
        editable=False,
    )

    name = models.CharField(
        max_length=200,
        db_index=True,
    )

    slug = models.SlugField(
        unique=True,
    )

    description = models.TextField(
        blank=True,
    )

    price = models.DecimalField(
        max_digits=10,
        decimal_places=2,
    )

    stock = models.PositiveIntegerField(
        default=0,
    )

    status = models.CharField(
        max_length=20,
        choices=Status.choices,
        default=Status.DRAFT,
    )

    category = models.ForeignKey(
        Category,
        on_delete=models.PROTECT,
        related_name="products",
    )

    image = models.ImageField(
        upload_to="products/",
        blank=True,
    )

    metadata = models.JSONField(
        default=dict,
        blank=True,
    )

    created_at = models.DateTimeField(
        auto_now_add=True,
    )

    updated_at = models.DateTimeField(
        auto_now=True,
    )

    def __str__(self):
        return self.name

Common Combinations

Required Short Text

python

1
name = models.CharField(max_length=200)

Optional Short Text

python

1
2
3
4
subtitle = models.CharField(
    max_length=200,
    blank=True,
)

Optional Long Text

python

1
description = models.TextField(blank=True)

Optional Date

python

1
2
3
4
published_at = models.DateTimeField(
    null=True,
    blank=True,
)

Unique Slug

python

1
slug = models.SlugField(unique=True)

Price

python

1
2
3
4
price = models.DecimalField(
    max_digits=10,
    decimal_places=2,
)

Creation Timestamp

python

1
2
3
created_at = models.DateTimeField(
    auto_now_add=True,
)

Update Timestamp

python

1
2
3
updated_at = models.DateTimeField(
    auto_now=True,
)

Optional File

python

1
2
3
4
document = models.FileField(
    upload_to="documents/",
    blank=True,
)

Optional Relationship

python

1
2
3
4
5
6
category = models.ForeignKey(
    Category,
    on_delete=models.SET_NULL,
    null=True,
    blank=True,
)

Required Protected Relationship

python

1
2
3
4
category = models.ForeignKey(
    Category,
    on_delete=models.PROTECT,
)

Common Mistakes

Confusing null and blank

null   → Controls database NULL
blank  → Controls validation

Using FloatField for Money

Avoid:

python

1
price = models.FloatField()

Prefer:

python

1
2
3
4
price = models.DecimalField(
    max_digits=10,
    decimal_places=2,
)

Using a Mutable Default Directly

Avoid:

python

1
data = models.JSONField(default={})

Prefer:

python

1
data = models.JSONField(default=dict)

Calling a Default Function

Avoid:

python

1
default=uuid.uuid4()

Prefer:

python

1
default=uuid.uuid4

Adding null=True to Text Fields

Usually avoid:

python

1
2
3
4
5
name = models.CharField(
    max_length=200,
    null=True,
    blank=True,
)

Prefer:

python

1
2
3
4
name = models.CharField(
    max_length=200,
    blank=True,
)

Forgetting on_delete

Incorrect:

python

1
category = models.ForeignKey(Category)

Correct:

python

1
2
3
4
category = models.ForeignKey(
    Category,
    on_delete=models.CASCADE,
)

Using null=True on ManyToManyField

Avoid:

python

1
2
3
4
tags = models.ManyToManyField(
    Tag,
    null=True,
)

Use:

python

1
2
3
4
tags = models.ManyToManyField(
    Tag,
    blank=True,
)

Mini Reference Summary

CharField          → Short text
TextField          → Long text
IntegerField       → Whole number
DecimalField       → Fixed-precision number
BooleanField       → True or False
DateField          → Date
DateTimeField      → Date and time
EmailField         → Email address
URLField           → Web address
SlugField          → URL-friendly text
FileField          → Uploaded file
ImageField         → Uploaded image
JSONField          → JSON data
UUIDField          → UUID identifier

ForeignKey         → Many-to-one
OneToOneField      → One-to-one
ManyToManyField    → Many-to-many

null               → Database NULL
blank              → Empty validation value
default            → Default value
unique             → No duplicate values
choices            → Limited allowed values
primary_key        → Main record identifier
db_index           → Database index
related_name       → Reverse relationship name
on_delete          → Related deletion behavior

Join the Newsletter

Practical insights on Django, backend systems, deployment, architecture, and real-world development — delivered without noise.

Get updates when new guides, learning paths, cheat sheets, and field notes are published.

No spam. Unsubscribe anytime.



There is no third-party involved so don't worry - we won't share your details with anyone.