DEV Community

Gopal Ghate
Gopal Ghate

Posted on

๐Ÿ—„๏ธ Django Models & ORM Deep Dive (Article 3)

In the previous article, we set up our first app and rendered a template successfully. Now, itโ€™s time to make our app dynamic by adding a database. Djangoโ€™s ORM (Object Relational Mapper) allows us to work with databases using Python classes โ€” no SQL required!

In this article, we will cover:

  • What are models and the Django ORM?

  • Defining fields and creating migrations.

  • Performing CRUD operations.

  • Relationships: One-to-One, One-to-Many, Many-to-Many.

  • Querying the database.

  • Quickly testing with sample data.

๐Ÿ— What is a Django Model?

A model is a Python class that maps to a database table. Each attribute in the class becomes a column in the table.

Example (blog/models.py):

from django.db import models


class Post(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    published_at = models.DateTimeField(auto_now_add=True)


    def __str__(self):
        return self.title
Enter fullscreen mode Exit fullscreen mode

Django will create a table named blog_post for this model.

๐Ÿ›  Creating Migrations

Migrations apply model changes to the database:

python manage.py makemigrations
python manage.py migrate
Enter fullscreen mode Exit fullscreen mode
  • makemigrations โ†’ Creates migration files.

  • migrate โ†’ Applies changes to the database.

โœ๏ธ CRUD Operations

** Create **

from blog.models import Post

Post.objects.create(title="My First Post", content="This is awesome!")
Enter fullscreen mode Exit fullscreen mode

** Read **

Post.objects.all() # Get all posts
Post.objects.first() # First post
Post.objects.filter(title__icontains="First")
Enter fullscreen mode Exit fullscreen mode

** Update **

post = Post.objects.get(id=1)
post.title = "Updated Title"
post.save()
Enter fullscreen mode Exit fullscreen mode

** Delete **

post = Post.objects.get(id=1)
post.delete()
Enter fullscreen mode Exit fullscreen mode

๐Ÿ”— Relationships Between Models

One-to-Many (ForeignKey)

class Comment(models.Model):
    post = models.ForeignKey(Post, related_name="comments", on_delete=models.CASCADE)
    text = models.TextField()
Enter fullscreen mode Exit fullscreen mode

Each comment belongs to one post.
Access comments: post.comments.all()

One-to-One

from django.contrib.auth.models import User

class AuthorProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    bio = models.TextField()
Enter fullscreen mode Exit fullscreen mode

Many-to-Many

class Tag(models.Model):
    name = models.CharField(max_length=50)
    posts = models.ManyToManyField(Post, related_name="tags")
Enter fullscreen mode Exit fullscreen mode

๐Ÿ” Querying the Database

# Exact match
Post.objects.filter(title="My First Post")


# Case-insensitive search
Post.objects.filter(title__icontains="first")


# Order results
Post.objects.order_by('-published_at')


# Access related objects
post = Post.objects.get(id=1)
comments = post.comments.all()
Enter fullscreen mode Exit fullscreen mode

๐Ÿงช Testing with Sample Data

You can test models directly in the Django shell:

python manage.py shell # Make sure in the project directory
Enter fullscreen mode Exit fullscreen mode

Inside the shell :

from blog.models import Post

Post.objects.create(title="Sample 1", content="Hello World")
Post.objects.create(title="Sample 2", content="Learning Django ORM")


for post in Post.objects.all():
    print(post.title)
Enter fullscreen mode Exit fullscreen mode

Or load fixtures from a JSON file:

python manage.py loaddata sample_posts.json
Enter fullscreen mode Exit fullscreen mode

๐Ÿ† Summary

  • Models map Python classes to database tables.

  • Use migrations to apply schema changes.

  • ORM provides easy CRUD operations.

  • Relationships (ForeignKey, OneToOne, ManyToMany) connect models.

  • Querysets allow powerful filtering.

  • Use Django shell or fixtures to test with sample data.

Top comments (0)