How to work with Django models and databases
Once your Django project is set up and running, the next step is to dive into one of the core components of any web application: managing data.
Django’s object-relational mapping (ORM) system makes it easy to define and work with models, which represent the structure of your database. Let’s explore how Django handles models and databases to power dynamic, data-driven applications.
What are Django models?
In Django, models define the structure of your database tables. They are Python classes that map directly to database tables, so you can interact with your data in a convenient, high-level way.
Each model class represents a table, and each model attribute represents a field in that table.
Django removes the need to write raw SQL queries by using its ORM system, which simplifies tasks like creating, updating, and managing database records.
How to create a Django model?
To create a model, you define a Python class inside the models.py file of one of your apps. Each attribute in the class represents a database field, and Django will automatically handle the underlying database structure when you run migrations.
Here’s an example of a simple model in Django:
# In your app's models.py file from django.db import models class Book(models.Model): title = models.CharField(max_length=200) author = models.CharField(max_length=100) published_date = models.DateField() isbn = models.CharField(max_length=13, unique=True) def __str__(self): return self.title
- title and author – these are character fields (CharField) with a maximum length.
- published_date – this is a date field (DateField).
- isbn – a character field (CharField) with a unique constraint (unique=True).
The __str__() method ensures that when you query for a book, it will return the book’s title as a string representation.
Model fields
In Django, model fields define the data type you want to store in your database. Each field type specifies how the data will be stored and validated.
Below are some of the most common field types:
- CharField – for short text (e.g. names).
name = models.CharField(max_length=100)
- TextField – for long text (e.g. descriptions).
description = models.TextField()
- IntegerField – for whole numbers.
age = models.IntegerField()
- FloatField – for decimal numbers.
price = models.FloatField()
- BooleanField – for True or False values.
is_active = models.BooleanField(default=True)
- DateField – for storing dates.
birth_date = models.DateField()
- DateTimeField – for storing both date and time.
created_at = models.DateTimeField(auto_now_add=True)
- ForeignKey – for creating a many-to-one relationship with another model.
user = models.ForeignKey(User, on_delete=models.CASCADE)
- ManyToManyField – for creating a many-to-many relationship between models.
tags = models.ManyToManyField(Tag)
Model relationships
Model relationships define how models are connected to each other. Django provides three main types of relationships:
- ForeignKey – defines a many-to-one relationship. One object in this model is linked to one object in another model (e.g., a post belongs to a user).
user = models.ForeignKey(User, on_delete=models.CASCADE)
- OneToOneField – defines a one-to-one relationship. Each object in one model is linked to exactly one object in another model (e.g., a user has one profile).
profile = models.OneToOneField(Profile, on_delete=models.CASCADE)
- ManyToManyField – defines a many-to-many relationship. Many objects of one model can be linked to many objects of another model (e.g., a post can have multiple tags, and each tag can belong to multiple posts).
tags = models.ManyToManyField(Tag)
These relationships let you create connections between models and establish links between data in your database.
Adding the model to the database
Once you’ve created your model, Django needs to translate it into a database table. This is done through migrations, which are files that Django uses to apply changes to the database schema and keep track of changes in your models.
Creating migrations
To create the migration file for your new model, run the following command:
python manage.py makemigrations
Django will analyze the changes in your models.py file and generate a migration file that describes those changes in a format that Django can apply to the database.
You’ll see output similar to this:
Migrations for 'myapp': myapp/migrations/0001_initial.py - Create model Book
Applying migrations
After generating the migration, apply it to the database using the migrate command:
python manage.py migrate
This command will create the necessary tables in your database. Now, the Book model is represented by a corresponding Book table in your database, and you can start adding, querying, and managing data.
Setting up the default database
Django supports multiple databases, so you can choose the best one for your project. By default, Django uses SQLite, which is lightweight, easy to set up, and ideal for development and small projects.
For production environments, we recommend more robust databases like PostgreSQL, MySQL, or MariaDB due to their scalability and performance.
In this tutorial, let’s start by setting up the default SQLite database.
Configuring the database in settings.py
By default, Django is configured to use SQLite, which comes pre-installed with Python, so no additional setup is needed. Here’s how to make sure your project is set up to use SQLite:
- Navigate to your project’s settings.py file, which is located in the project folder (myproject/myproject/settings.py).
- Go to the DATABASES section in settings.py, where Django has already configured SQLite as the default database. It should look like this:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': BASE_DIR / 'db.sqlite3', } }
- ENGINE – specifies the database backend (in this case, SQLite).
- NAME – the path to the SQLite database file (db.sqlite3). Django will automatically create this file when you run the initial migration.
Applying migrations for default tables
After confirming your database settings, you need to apply the initial migrations to set up the default tables (like users and sessions). Run the following command:
python manage.py migrate
This command will create the db.sqlite3 file in your project directory’s root and set up all the necessary tables for your application to run.
Once the migrations are complete, check that db.sqlite3 was created in your project folder. This file stores your database locally and will grow as you add more data.
Using other databases for Django production
Once you’ve set up the default SQLite database for development, you may need to integrate a more robust database management system (DBMS) as your project grows.
Django supports multiple DBMSs, including PostgreSQL, MySQL, MariaDB, and Oracle. Each has its own strengths and requires a specific configuration for integration with Django.
Overview of other Supported databases in Django
Let’s take a look at each of the options and how they differ from SQLite:
PostgreSQL
A powerful, open-source database with advanced features, such as support for complex queries, data types like JSON, and full-text search. It’s highly recommended for production Django applications due to its scalability, robustness, and feature set.
PostgreSQL is known for strictly adhering to SQL standards and is reliable for complex and large-scale applications.
- Setup – PostgreSQL requires installing the psycopg2 package, which acts as the adapter between Django and PostgreSQL.
- Configuration – in addition to the default ENGINE and NAME parameters for SQLite, PostgreSQL also requires USER, PASSWORD, HOST, and PORT. These parameters are configured in the settings.py file, under the DATABASES section:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'mydatabase', 'USER': 'mydatabaseuser', 'PASSWORD': 'mypassword', 'HOST': 'localhost', 'PORT': '5432', } }
- Differences – unlike SQLite, PostgreSQL is a fully-featured database that supports multiple concurrent users, advanced querying, and transactions. You’ll need to install PostgreSQL on your server, create a database and user, and configure more complex settings.
MySQL and MariaDB
Both are fast and reliable relational databases widely used in web development. MySQL is known for its speed, while MariaDB, a fork of MySQL, focuses on community-driven development and is fully compatible with MySQL.
These databases are excellent for high-traffic web applications and are often favored for their performance.
- Setup – MySQL and MariaDB both use the mysqlclient package to interface with Django.
- Configuration – both use the same parameters as PostgreSQL, which are configured in the settings.py file under the DATABASES section:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', # or 'django.db.backends.mariadb' for MariaDB 'NAME': 'mydatabase', 'USER': 'mydatabaseuser', 'PASSWORD': 'mypassword', 'HOST': 'localhost', 'PORT': '3306', } }
- Differences – Compared to SQLite, MySQL and MariaDB are known for their performance with large datasets and high-traffic web applications. They support multiple storage engines, fast reads, and can handle millions of queries quickly.
Oracle and Microsoft SQL Server
These enterprise-grade databases offer significant power, especially for large-scale web applications.
However, their setup can be more complex, and they are typically used in specific enterprise environments where the business already relies on Oracle or SQL Server for other software.
- Setup – both require additional drivers for integration with Django. For Oracle, you’ll need cx_Oracle, and for SQL Server, you’ll need pyodbc.
- Configuration – each of these systems requires a more complex setup, including server installation, driver installation, and configuring database credentials in the settings.py file.
- Differences – Oracle and SQL Server offer enterprise-grade features such as advanced transaction handling, optimized performance, and integration with large-scale systems. Their setup is more complex than SQLite and is typically handled by specialized database administrators.
Choosing the right database for your project
With so many different databases available, how do you choose the right one? Here’s a quick, to-the-point breakdown:
- Development and testing – stick with SQLite. It’s simple, requires no setup, and is ideal for local testing.
- Small-scale production – for smaller, low-traffic web applications, MySQL or MariaDB may be a better choice. They offer better performance than SQLite and are easier to learn than PostgreSQL.
- Large-scale production – PostgreSQL is highly recommended for Django projects that require scalability, security, and advanced features.
- Enterprise environments – if you work in an enterprise setting that already uses Oracle or SQL Server for other applications, these databases are likely the best choice due to integration requirements.
Setting up PostgreSQL with Django
In this section, we’ll walk through the process of integrating PostgreSQL with Django, as it’s one of the most commonly used databases for production applications.
- To integrate PostgreSQL with Django, you first need to install it on your system:
sudo apt update sudo apt install postgresql postgresql-contrib
- Django uses the psycopg2 package to interact with PostgreSQL. Install it using pip:
pip install psycopg2
- Switch to the PostgreSQL user:
sudo -u postgres psql
- Create a new database:
CREATE DATABASE mydatabase;
- Create a user with a password:
CREATE USER mydatabaseuser WITH PASSWORD 'mypassword';
- Grant the user all privileges on the database:
GRANT ALL PRIVILEGES ON DATABASE mydatabase TO mydatabaseuser;
- Exit the PostgreSQL shell:
\q
- Open your settings.py file and locate the DATABASES section. Modify it for PostgreSQL as follows:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'mydatabase', 'USER': 'mydatabaseuser', 'PASSWORD': 'mypassword', 'HOST': 'localhost', # Use '127.0.0.1' if 'localhost' doesn't work 'PORT': '5432', # Default PostgreSQL port } }
The actual PASSWORD and USER values should match the ones you set in Step 5.
- Now that your database is configured, apply your project’s migrations to set up the necessary tables in PostgreSQL:
python manage.py migrate
This command will create the required tables in your PostgreSQL database.
- Finally, run the Django development server to verify that the PostgreSQL integration is successful:
python manage.py runserver
Open http://127.0.0.1:8000/ in your browser. If the Django welcome page appears without errors, your database connection is working correctly.
Conclusion
In summary, Django makes working with databases simple and efficient. Its models let you define your database structure using Python, and migrations automatically handle database updates.
For development, SQLite is ideal, but for larger, production-ready projects, PostgreSQL, MySQL, or MariaDB offer better scalability and performance. Don’t worry; Django’s flexibility ensures your app can scale seamlessly as it grows.
Next, you can start working with Django views and templates to build dynamic content for your site.
Django models FAQ
How do Django models work?
Django models define the database structure using Python classes. Each model corresponds to a database table, and its attributes represent the table’s fields. When you run migrations, Django creates or updates the database tables based on your models.
How do I create a Django model?
To create a Django model, define a class in models.py that inherits from django.db.models.Model and specify the fields. Then, run python manage.py makemigrations and python manage.py migrate to update the database.
Can I use multiple databases with Django models?
Yes, Django supports multiple databases. You can configure them in settings.py and use the using() method to specify which database a query should use.