Django Models & Databases
Models in Django are Python classes that represent database tables. They define the structure of your data and provide an abstraction layer for database operations.
What are Django Models?
Django models:
- Are Python classes that subclass
django.db.models.Model
- Each attribute represents a database field
- Provide methods for querying the database
- Handle data validation
- Define relationships between data
Creating a Model
Define models in your app's models.py
file:
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.CharField(max_length=100)
published_date = models.DateField()
isbn = models.CharField(max_length=13)
pages = models.IntegerField()
price = models.DecimalField(max_digits=5, decimal_places=2)
in_stock = models.BooleanField(default=True)
def __str__(self):
return self.title
Model Field Types
Django provides many field types:
AutoField
- Integer field that auto-incrementsBigAutoField
- 64-bit integer that auto-incrementsBooleanField
- True/False fieldCharField
- String field for small stringsDateField
- Date fieldDateTimeField
- Date and time fieldDecimalField
- Fixed-precision decimal numberEmailField
- Email address fieldFileField
- File upload fieldFloatField
- Floating-point numberImageField
- Image upload fieldIntegerField
- Integer fieldTextField
- Large text fieldURLField
- URL fieldUUIDField
- Universally unique identifier
Field Options
Field types accept optional arguments:
null
- If True, Django will store NULL in database (default: False)blank
- If True, field is allowed to be blank (default: False)choices
- Sequence of 2-tuples to use as choicesdefault
- Default value for the fieldhelp_text
- Extra help text to be displayed with the form widgetprimary_key
- If True, this field is the primary keyunique
- If True, field must be uniqueverbose_name
- Human-readable name
Model Methods
Add custom methods to your models:
class Book(models.Model):
# ... fields ...
def is_expensive(self):
return self.price > 50
def get_absolute_url(self):
return reverse('book_detail', args=[str(self.id)])
Model Meta Options
Use Meta class to add metadata to your model:
class Book(models.Model):
# ... fields ...
class Meta:
ordering = ['title']
verbose_name = 'book'
verbose_name_plural = 'books'
Model Relationships
Django supports three main types of relationships:
- Many-to-one:
ForeignKey
- Many-to-many:
ManyToManyField
- One-to-one:
OneToOneField
ForeignKey Example
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
ManyToManyField Example
class Category(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
title = models.CharField(max_length=100)
categories = models.ManyToManyField(Category)
OneToOneField Example
class Place(models.Model):
name = models.CharField(max_length=50)
address = models.CharField(max_length=80)
class Restaurant(models.Model):
place = models.OneToOneField(
Place,
on_delete=models.CASCADE,
primary_key=True
)
serves_hot_dogs = models.BooleanField(default=False)
on_delete Options
When using relationships, specify what happens when referenced object is deleted:
CASCADE
- Delete objects that had a foreign key pointing to itPROTECT
- Prevent deletion of referenced objectSET_NULL
- Set foreign key to NULLSET_DEFAULT
- Set foreign key to default valueSET()
- Set foreign key to value passed to SET()DO_NOTHING
- Take no action (database may raise error)
Migrations
Migrations are Django's way of propagating changes to your models into your database schema:
# Create migrations for your changes
python manage.py makemigrations
# Apply migrations to database
python manage.py migrate
Querying the Database
Django provides a powerful ORM for querying the database:
Creating Objects
# Create and save immediately
book = Book(title="Django for Beginners", author="William S. Vincent")
book.save()
# Create and save in one step
book = Book.objects.create(title="Django for Professionals", author="William S. Vincent")
Retrieving Objects
# Get all books
all_books = Book.objects.all()
# Get a single book by id
book = Book.objects.get(id=1)
# Filter books
expensive_books = Book.objects.filter(price__gt=50)
django_books = Book.objects.filter(title__contains="Django")
recent_books = Book.objects.filter(published_date__year=2023)
Updating Objects
# Update a single object
book = Book.objects.get(id=1)
book.price = 29.99
book.save()
# Update multiple objects
Book.objects.filter(published_date__year=2020).update(price=19.99)
Deleting Objects
# Delete a single object
book = Book.objects.get(id=1)
book.delete()
# Delete multiple objects
Book.objects.filter(published_date__year=2010).delete()
QuerySet Methods
Common QuerySet methods:
all()
- Returns all objectsfilter()
- Returns objects matching given parametersexclude()
- Returns objects not matching given parametersget()
- Returns single object matching parameterscreate()
- Creates and saves a new objectcount()
- Returns count of objectsorder_by()
- Orders the resultsvalues()
- Returns dictionaries instead of model instancesvalues_list()
- Returns tuples instead of model instances
Field Lookups
Field lookups specify how to match fields:
exact
- Exact match (default lookup)iexact
- Case-insensitive exact matchcontains
- Case-sensitive containment testicontains
- Case-insensitive containment testin
- In a given listgt
- Greater thangte
- Greater than or equal tolt
- Less thanlte
- Less than or equal tostartswith
- Case-sensitive starts-withistartswith
- Case-insensitive starts-withendswith
- Case-sensitive ends-withiendswith
- Case-insensitive ends-withrange
- Range test (inclusive)
Aggregation
Django supports database aggregation:
from django.db.models import Avg, Max, Min, Sum, Count
# Average price of all books
Book.objects.all().aggregate(Avg('price'))
# Max price of books in stock
Book.objects.filter(in_stock=True).aggregate(Max('price'))
# Count books by author
Book.objects.values('author').annotate(count=Count('id'))
Model Inheritance
Django supports three styles of model inheritance:
- Abstract base classes: Parent model holds common info but isn't a database table
- Multi-table inheritance: Each model has its own database table
- Proxy models: Change Python behavior without changing database structure
Abstract Base Class Example
class BaseModel(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
class Book(BaseModel):
title = models.CharField(max_length=100)
# ...
Registering Models with Admin
To make models editable in the admin interface:
from django.contrib import admin
from .models import Book
@admin.register(Book)
class BookAdmin(admin.ModelAdmin):
list_display = ('title', 'author', 'price')
list_filter = ('author', 'in_stock')
search_fields = ('title', 'author')
Database Configuration
Django supports multiple databases. Configure in settings.py
:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'mydatabase',
'USER': 'mydatabaseuser',
'PASSWORD': 'mypassword',
'HOST': '127.0.0.1',
'PORT': '5432',
}
}
Supported Databases
Django officially supports:
- PostgreSQL
- MySQL
- SQLite
- Oracle
Model Best Practices
- Use descriptive field names
- Add
__str__
methods to all models - Use related_name for reverse relationships
- Consider abstract base classes for common fields
- Use verbose_name for better admin display
- Add indexes for frequently queried fields
- Use select_related and prefetch_related for performance