Models And Databases


In Django, models are the core component for defining the structure of your data. They represent the database tables and act as a bridge between the database and your application. In Django, models are defined as Python classes, and Django uses these classes to create, read, update, and delete records in the database.

1. Models :

A model in Django is a Python class that inherits from django.db.models.Model. The class attributes represent the fields of the database table. With all of this, Django gives you an automatically-generated database-access API.

1.1 Defining a Model :

from django.db import models

class Person(models.Model):
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)
    birth_date = models.DateField()
    email = models.EmailField()

    def __str__(self):
        return f'{self.first_name} {self.last_name}'
  • first_name ,last_name ,birth_date and email are fields of the model. Each field is specified as a class attribute, and each attribute maps to a database column.

  • models.CharField(max_length=100): This defines a string field with a maximum length of 100 characters.

  • models.DateField(): This defines a date field to store dates (without time).

  • models.EmailField(): This field is for storing email addresses and provides validation for correct email formats.

The above Person model would create a database table like this:

CREATE TABLE myapp_person (
    "id" bigint NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
    "first_name" varchar(30) NOT NULL,
    "last_name" varchar(30) NOT NULL
);
  • An id field is added automatically, but this behavior can be overridden.

  • The CREATE TABLE SQL in this example is formatted using PostgreSQL syntax, but it’s worth noting Django uses SQL tailored to the database backend specified in your settings file.

1.2 Field Types :

Django provides various field types to represent different types of data:

  • Text fields: CharField, TextField

  • Date and Time fields: DateField, TimeField, DateTimeField

  • Integer and Floating Point fields: IntegerField, FloatField, DecimalField

  • Boolean fields: BooleanField

  • Choice fields: ChoiceField

  • File fields: FileField, ImageField

  • Foreign Key fields: ForeignKey, ManyToManyField, OneToOneField

1.3 Field Options :

Each field takes a certain set of field-specific arguments. Example: null, blank, choices, default, primary_key, unique

2. Models and Relationships :

Django models support relationships between different models:

  • Foreign Key (ForeignKey): This creates a many-to-one relationship (e.g., each Book has one Author, but each Author can have multiple Books).
class Author(models.Model):
    name = models.CharField(max_length=100)

class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.ForeignKey(Author, on_delete=models.CASCADE)
  • Many-to-Many (ManyToManyField): This creates a many-to-many relationship (e.g., a Student can be enrolled in many Courses, and each Course can have many Students).
class Course(models.Model):
    name = models.CharField(max_length=100)

class Student(models.Model):
    name = models.CharField(max_length=100)
    courses = models.ManyToManyField(Course)
  • One-to-One (OneToOneField): This creates a one-to-one relationship (e.g., each User has one Profile).
class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    bio = models.TextField()

3. Database Migrations :

Once models are defined, Django uses migrations to apply changes to the database. Migrations are versioned scripts that track the changes made to the models.

  • To create a migration for a new model or change in a model:
python manage.py makemigrations
  • To apply the migration to the database:
python manage.py migrate

4. Database Queries :

Django provides a powerful ORM(Object-Relational Mapping) to interact with the database. Using the Django ORM, you can perform queries without writing raw SQL.

  • Creating a record:
person = Person(first_name='John', last_name='Doe', birth_date='2000-01-01', email='john.doe@example.com')
person.save()
  • Querying records :
# Get all persons
persons = Person.objects.all()

# Get a single person by ID
person = Person.objects.get(id=1)

# Filtering
young_persons = Person.objects.filter(birth_date__gte='2000-01-01')

# Ordering
persons_sorted = Person.objects.order_by('last_name')
  • Updating a record :
person = Person.objects.get(id=1)
person.email = 'new.email@example.com'
person.save()
  • Deleting a record :
person = Person.objects.get(id=1)
person.delete()

5. Django Database Configuration:

Django uses the DATABASES setting in settings.py to configure the connection to the database.

Example for using SQLite (default in Django) :
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

You can switch to other databases like PostgreSQL, MySQL, or Oracle by changing the ENGINE and adding the necessary credentials (username, password, host, etc.).

Example for using PostgreSQL:
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'mydatabase',
        'USER': 'myuser',
        'PASSWORD': 'mypassword',
        'HOST': 'localhost',
        'PORT': '5432',
    }
}

6. Database Indexing :

Django allows you to optimise your database queries by adding indexes to specific fields.

  • Adding indexes to a model :
class Person(models.Model):
    first_name = models.CharField(max_length=100, db_index=True)
    last_name = models.CharField(max_length=100)

    class Meta:
        indexes = [
            models.Index(fields=['last_name']),
        ]
  • Using unique constraints:
class User(models.Model):
    username = models.CharField(max_length=100, unique=True)

7. Advanced Features in Django Models:

  • Model Meta options: You can add various options in the inner Meta class of a model to configure database behavior, such as ordering, verbose_name, db_table, etc.
class Person(models.Model):
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)

    class Meta:
        ordering = ['last_name']
        verbose_name = 'Person'
        db_table = 'person_table'
  • Signals: Django signals allow you to take actions when certain events occur in the database, such as when a model is saved or deleted.
from django.db.models.signals import pre_save, post_save
from django.dispatch import receiver

@receiver(post_save, sender=Person)
def notify_admin(sender, instance, created, **kwargs):
    if created:
        print(f'New person created: {instance.first_name} {instance.last_name}')

8. Admin Interface and Models :

Django’s admin interface allows you to manage your models easily through a web interface. You can register your models in admin.py to make them accessible in the Django admin dashboard.

from django.contrib import admin
from .models import Person

admin.site.register(Person)

This will make the Person model available in the admin interface.

Summary:

  • Models: In Django, models define the structure of the database and act as a bridge to interact with the database.

  • Fields: Django provides various field types to represent different kinds of data.

  • Relationships: Django supports defining relationships between models, such as Foreign Key, Many-to-Many, and One-to-One.

  • ORM: Django's Object-Relational Mapping (ORM) allows you to perform CRUD operations on the database using Python code.

  • Migrations: Django uses migrations to manage changes to the database schema over time.

1
Subscribe to my newsletter

Read articles from Abhay Pratap Maurya directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Abhay Pratap Maurya
Abhay Pratap Maurya