13. Database and Migrations#
Django’s
ORM
(Object-Relational Mapping) provides a powerful and flexible way to interact with databases.This tutorial will guide you through setting up models, creating and applying
migrations
, and managing your database schema. We’ll use a blogging application withPost
,User
, andComment
models as examples.
13.1. Setting Up Your Models#
Let’s start by defining our models in
blog/models.py
.Here is a table listing the
supported field types
inDjango's django.db.models
module along with examples for each
Field Type |
Description |
Example |
---|---|---|
CharField |
A string field, for small- to large-sized strings. |
|
TextField |
A large text field. Use this for large amounts of text. |
|
IntegerField |
An integer field. |
|
FloatField |
A floating-point number field. |
|
BooleanField |
A boolean field. |
|
DateField |
A date field. |
|
DateTimeField |
A date and time field. |
|
TimeField |
A time field. |
|
EmailField |
An Email field. |
|
URLField |
A URL field. |
|
SlugField |
A slug field. |
|
FileField |
A file upload field. |
|
ImageField |
An image upload field. |
|
ForeignKey |
A many-to-one relationship. |
|
OneToOneField |
A one-to-one relationship. |
|
ManyToManyField |
A many-to-many relationship. |
|
DecimalField |
A fixed-precision decimal number field. |
|
PositiveIntegerField |
An integer field for positive values only. |
|
PositiveSmallIntegerField |
A small integer field for positive values only. |
|
SmallIntegerField |
A small integer field. |
|
DurationField |
A field for storing periods of time. |
|
UUIDField |
A field for storing universally unique identifiers. |
|
BinaryField |
A field for storing binary data. |
|
JSONField |
A field for storing JSON data. |
|
13.1.1. Post Model#
CharField: Represents a short-to-mid-sized string.
ForeignKey: Creates a
many-to-one
relationship to theUser
model.TextField: Represents large text fields.
DateTimeField: Represents a
date
andtime
field, with default set to the current time.from django.db import models from django.utils import timezone from django.contrib.auth.models import User class Post(models.Model): title = models.CharField(max_length=80) author = models.ForeignKey(User, on_delete=models.CASCADE) content = models.TextField() date_posted = models.DateTimeField(default=timezone.now) def __str__(self): return self.title
13.2. Creating and Applying Migrations#
After defining your models, you need to create and apply
migrations
to update the database schema.
13.2.1. Creating Migrations#
Run the following command to create
migrations
based on the changes in your modelsThis command generates a migration file in the
blog/migrations
directory.python manage.py makemigrations
13.2.2. Applying Migrations#
To apply the migrations and update the database schema, run:
This command applies the
migrations
to your database, creating the necessarytables
andfields
.python manage.py migrate
13.3. Creating Demo Data#
First, ensure you have access to Django’s
shell
to execute Python code within the context of your Django project. Run the following command:python manage.py shell
Within the shell, you can create instances of your models.
from django.contrib.auth.models import User from blog.models import Post, Comment from django.utils import timezone # Create a user user = User.objects.create_user(username='john_doe', email='john@example.com', password='password123') # Create some posts post1 = Post.objects.create(title='First Post', author=user, content='This is the content of the first post', date_posted=timezone.now()) post2 = Post.objects.create(title='Second Post', author=user, content='This is the content of the second post', date_posted=timezone.now()) # Create comments for post1 comment1 = Comment.objects.create(post=post1, author=user, content='This is the first comment on the first post', date_posted=timezone.now()) comment2 = Comment.objects.create(post=post1, author=user, content='This is the second comment on the first post', date_posted=timezone.now()) # Create a comment for post2 comment3 = Comment.objects.create(post=post2, author=user, content='This is the first comment on the second post', date_posted=timezone.now())
If you facing any problem, you can re-create database, but your all data will be gone (including super-user)
In default, Django use
db.sqlite3
to store all datarm db.sqlite3
13.4. ORM Queries#
13.4.1. Basic Queries#
Retrieve all posts
Filter posts by author
Get a single post by ID
# Retrieve all posts all_posts = Post.objects.all() # Filter posts by author author_posts = Post.objects.filter(author=user) # Get a single post by ID single_post = Post.objects.get(id=1)
13.4.3. Advanced Queries [field lookups]#
Django’s
ORM
usesfield lookups
, which are used to create complex queries.Here’s a table of common
field lookups
with their purpose and examples:
Function |
Purpose |
Example |
---|---|---|
exact |
Exact match |
|
iexact |
Case-insensitive exact match |
|
contains |
Contains substring |
|
icontains |
Case-insensitive contains |
|
in |
Value is in a given list |
|
gt |
Greater than |
|
gte |
Greater than or equal to |
|
lt |
Less than |
|
lte |
Less than or equal to |
|
startswith |
Starts with substring |
|
istartswith |
Case-insensitive starts with substring |
|
endswith |
Ends with substring |
|
iendswith |
Case-insensitive ends with substring |
|
range |
Value is within a range |
|
date |
Match a specific date |
|
year |
Match a specific year |
|
month |
Match a specific month |
|
day |
Match a specific day |
|
week_day |
Match a specific day of the week |
|
isnull |
Check for NULL (or not NULL) |
|
Retrieve posts containing a keyword
Retrieve posts published in the last 7 days
Order posts by date posted (newest first)
# Retrieve posts containing a keyword keyword_posts = Post.objects.filter(content__icontains='content') # Retrieve posts published in the last 7 days recent_posts = Post.objects.filter(date_posted__gte=timezone.now() - timezone.timedelta(days=7)) # Order posts by date posted (newest first) ordered_posts = Post.objects.all().order_by('-date_posted')
13.5. Working with the Admin Interface#
Register your models with the
admin
interface to manage them through Django’s admin panel.
13.5.1. Registering Models#
In
blog/admin.py
, register your models:This will make the
Post
andComment
models accessible in theadmin
interface.from django.contrib import admin from .models import Post, Comment admin.site.register(Post) admin.site.register(Comment)
13.1.2. Comment Model#
ForeignKey to Post and User: Each comment is associated with a specific post and user.