Skip to main content

Django Model Fields

In Django's powerful ORM system, model fields are the building blocks that define the data structure of your application. Understanding field types and their options is essential for creating effective Django models.

Introduction to Django Model Fields​

Django model fields represent the columns in your database table. Each field corresponds to a specific data type and has its own validation rules, formatting options, and constraints. Django provides a wide range of built-in field types designed to handle different kinds of data, from text and numbers to dates and binary data.

When you define a model class in Django, you specify its fields as class attributes:

python
from django.db import models

class Product(models.Model):
name = models.CharField(max_length=100)
price = models.DecimalField(max_digits=10, decimal_places=2)
description = models.TextField(blank=True)
created_at = models.DateTimeField(auto_now_add=True)

In this example, we've defined a Product model with four fields, each with a specific type and configurations.

Common Field Types​

Django provides numerous field types to handle different data. Let's explore the most commonly used ones:

Character Fields​

CharField​

Used for string data with a limited length.

python
title = models.CharField(max_length=100)
  • max_length is required and defines the maximum number of characters allowed

TextField​

For large text content with no length limitation.

python
content = models.TextField()

Numeric Fields​

IntegerField​

Stores integers.

python
quantity = models.IntegerField(default=0)

FloatField​

Stores floating-point numbers.

python
weight = models.FloatField()

DecimalField​

For storing decimal numbers with exact precision.

python
price = models.DecimalField(max_digits=6, decimal_places=2)
  • max_digits: Total number of digits
  • decimal_places: How many of those digits are decimal places

Boolean Fields​

BooleanField​

Stores True or False values.

python
is_active = models.BooleanField(default=True)

Date and Time Fields​

DateField​

Stores a date.

python
launch_date = models.DateField()

TimeField​

Stores a time.

python
meeting_time = models.TimeField()

DateTimeField​

Stores both date and time.

python
created_at = models.DateTimeField(auto_now_add=True)
modified_at = models.DateTimeField(auto_now=True)
  • auto_now_add=True: Automatically set the field to the current date/time when the object is first created
  • auto_now=True: Automatically update the field to the current date/time whenever the object is saved

Relationship Fields​

ForeignKey​

Creates a many-to-one relationship between models.

python
category = models.ForeignKey('Category', on_delete=models.CASCADE)
  • on_delete: Specifies what happens when the referenced object is deleted

ManyToManyField​

Creates a many-to-many relationship.

python
tags = models.ManyToManyField('Tag')

OneToOneField​

Creates a one-to-one relationship.

python
profile = models.OneToOneField('UserProfile', on_delete=models.CASCADE)

File Fields​

FileField​

For uploading and storing files.

python
document = models.FileField(upload_to='documents/')

ImageField​

For image files with additional validation.

python
photo = models.ImageField(upload_to='photos/%Y/%m/%d/')
  • upload_to: Specifies the directory where files will be uploaded

Common Field Options​

Most field types accept a common set of arguments that customize their behavior:

null​

Controls whether Django will store empty values as NULL in the database.

python
middle_name = models.CharField(max_length=100, null=True)

blank​

Controls whether the field is allowed to be blank in forms.

python
bio = models.TextField(blank=True)

Note: null is database-related, while blank is validation-related. For string-based fields, using blank=True, null=False is recommended to avoid having two possible values for "no data" (NULL and empty string).

choices​

Limits the field to a set of choices.

python
SHIRT_SIZES = [
('S', 'Small'),
('M', 'Medium'),
('L', 'Large'),
]
size = models.CharField(max_length=1, choices=SHIRT_SIZES)

default​

Sets a default value for the field.

python
is_active = models.BooleanField(default=True)
quantity = models.IntegerField(default=1)

help_text​

Provides help text for forms.

python
email = models.EmailField(help_text="Please enter a valid email address")

unique​

Ensures the field value is unique throughout the table.

python
username = models.CharField(max_length=30, unique=True)

verbose_name​

A human-readable name for the field.

python
first_name = models.CharField(max_length=30, verbose_name="First name")

Practical Example: Building a Blog Application​

Let's build a simple blog application to demonstrate how different field types work together in real-world models:

python
from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone

class Category(models.Model):
name = models.CharField(max_length=100, unique=True)
slug = models.SlugField(max_length=100, unique=True)
description = models.TextField(blank=True)

class Meta:
verbose_name_plural = "Categories"

def __str__(self):
return self.name

class Tag(models.Model):
name = models.CharField(max_length=50, unique=True)
slug = models.SlugField(max_length=50, unique=True)

def __str__(self):
return self.name

class Post(models.Model):
STATUS_CHOICES = [
('draft', 'Draft'),
('published', 'Published'),
]

title = models.CharField(max_length=200)
slug = models.SlugField(max_length=200, unique_for_date='publish_date')
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='blog_posts')
category = models.ForeignKey(Category, on_delete=models.PROTECT)
tags = models.ManyToManyField(Tag, blank=True)
content = models.TextField()
featured_image = models.ImageField(upload_to='blog/%Y/%m/', blank=True)
excerpt = models.TextField(blank=True)

publish_date = models.DateTimeField(default=timezone.now)
created_date = models.DateTimeField(auto_now_add=True)
updated_date = models.DateTimeField(auto_now=True)

status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='draft')
views = models.PositiveIntegerField(default=0)
is_featured = models.BooleanField(default=False)

class Meta:
ordering = ('-publish_date',)

def __str__(self):
return self.title

This example demonstrates:

  1. Using CharField for short text like titles and names
  2. Using SlugField for URL-friendly fields
  3. Various relationship fields:
    • ForeignKey for author and category (many-to-one)
    • ManyToManyField for tags (many-to-many)
  4. Using TextField for long text content
  5. ImageField for storing blog featured images
  6. Different date fields with auto settings
  7. Choices for status field
  8. Numeric fields for tracking views

Custom Field Validation​

You can enforce custom validation by overriding the clean method in your model:

python
from django.core.exceptions import ValidationError

class Product(models.Model):
name = models.CharField(max_length=100)
price = models.DecimalField(max_digits=10, decimal_places=2)
sale_price = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True)

def clean(self):
if self.sale_price and self.sale_price >= self.price:
raise ValidationError("Sale price must be less than the regular price.")

Creating Custom Model Fields​

If the built-in fields don't meet your needs, you can create custom fields. Here's a simple example of a custom RGB color field:

python
from django.db import models

class RGBColorField(models.CharField):
def __init__(self, *args, **kwargs):
kwargs['max_length'] = 7
super().__init__(*args, **kwargs)

def clean(self, value, model_instance):
value = super().clean(value, model_instance)
if value and not value.startswith('#'):
value = f'#{value}'
if value and not re.match(r'^#([A-Fa-f0-9]{6})$', value):
raise ValidationError('Enter a valid hex color code, e.g., #FF0000')
return value

class Design(models.Model):
name = models.CharField(max_length=100)
background_color = RGBColorField(default='#FFFFFF')
text_color = RGBColorField(default='#000000')

Summary​

Django model fields are powerful tools for defining your data structure. They provide:

  • Type checking and validation
  • Appropriate HTML form rendering
  • Conversion between Python and database types
  • A wide range of built-in options for customization

By carefully selecting the appropriate field types and options, you can create a robust data model that serves as a solid foundation for your Django application.

Exercises​

  1. Create a model for a library system with books, authors, and categories.
  2. Implement a model for an e-commerce product with variations (e.g., size, color) using relationships.
  3. Build a user profile model that extends the built-in Django user model with additional fields.

Additional Resources​

Understanding Django model fields thoroughly will give you the ability to design efficient and flexible database schemas, which is crucial for building scalable Django applications.



If you spot any mistakes on this website, please let me know at feedback@compilenrun.com. I’d greatly appreciate your feedback! :)