A database relationship describes the connection between different database tables. The relations determine how to store and retrieve data. Django works well with relational database systems (RDBMS). It, therefore, supports database table relationships.

The types of relationships depend on the requirements of your application and the data it models. Good relations between Django models and the database improve data maintenance. That includes improving query performance and reducing data duplication.

You can learn how Django database relationships affect application performance by exploring the three main types of relationship.

Database Relationships

Relational database systems support three types of database relationships. These relations are one-to-many, many-to-many, and one-to-one. The type of database relation affects your application's use cases.

Django models represent database tables in the app. You must create good relations between tables to create a good database system. Database relations determine how to store and present data in your application.

To understand database relations, start by creating a Django project named Hoods. The app will be a neighborhood social network. It will manage various neighborhoods' social activities, security, and businesses.

Residents can register, sign in, and create profiles. They can also create posts and business adverts for everyone to see.

To get started, create a database that will store all neighborhood data. Then, you will create the Profile, NeighborHood, Business, and Post models. To create the models, you must determine the relationship the database tables need.

One-to-One Database Relationship

A one-to-one relationship implies a record in one Django model relates to another record in another model. The two records depend on one another. In this case, the Profile model depends on the User model to create resident profiles.

So there can only be one profile for each resident registered on the app. Also, without a user, a profile cannot exist.

        from django.db import models
from django.contrib.auth.models import User
 
class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
    name = models.CharField(max_length=80, blank=True)
    bio = models.TextField(max_length=254, blank=True)
    profile_picture = CloudinaryField('profile_picture', default='default.png')
    location = models.CharField(max_length=50, blank=True, null=True)
    email = models.EmailField(null=True)
 
    def __str__(self):
        return f'{self.user.username} profile'

Django's User model is a built-in authentication model in Django. You don't have to create a model for it. Instead, import it from django.contrib.auth. The OneToOneField() on the Profile model defines a one-to-one relationship.

The on_delete=models.CASCADE argument prevents the deletion of one of these records. You must delete the records from both tables.

You can use the Django admin interface to visualize the relationship in your app. To log in to Django admin, you must register as an admin user known as a superuser.

Create a superuser by running the following command on the terminal:

        python manage.py createsuperuser
    

There will be a prompt to enter your username, email, and password. Once you've done so, start the server.

Open the admin page in a browser using the URL http://127.0.0.1:8000/admin.

You will see the admin page where you can log in with the credentials you created earlier. Once logged in, you will see the Groups and Users objects. The Django authentication framework manages these two models. At the bottom, you will see the Profile model.

Open the Profile model and proceed to add a profile. You will see it appears as follows:

Django admin displaying relation between profile and user models

Notice that you have the option to create a profile for a user. The OneToOneField() data type allows you to create profiles for authenticated users. This is how the app administers one-to-one relationships.

One-to-Many Relationships

A one-to-many relationship implies that one record in a model associates with many records in another model. It is also referred to as a many-to-one relationship.

In your case, one admin can create several neighborhoods. But each neighborhood can only belong to one admin. You can use the ForeignKey data type to define such a relationship.

Django has an in-built admin interface. You don't have to create a model for it. The admin has the right to manage content and visualize the app from the admin panel.

The model that accommodates many records will have the ForeignKey. It defines the relationship as one-to-many. The code below shows where to place the key.

        class NeighbourHood(models.Model):
    admin = models.ForeignKey("Profile", on_delete=models.CASCADE, related_name='hood')
    name = models.CharField(max_length=50)
    location = models.CharField(max_length=60)
    hood_logo = CloudinaryField('hood_logo', default='default.png')
    description = models.TextField()
    health_tell = models.IntegerField(null=True, blank=True)
    police_number = models.IntegerField(null=True, blank=True)
    Count= models.IntegerField(null=True, blank=True)
 
    def __str__(self):
        return f'{self.name} hood'

You can see the relationship on the app as illustrated in the picture:

Neigborhood model shows Admin choice added

The NeighborHood model now has an admin. For anyone to create a neighborhood, they must have admin rights. And one neighborhood cannot have many administrators.

Many-to-Many Database Relationships

In many-to-many relationships, many records in one model associate with others in another. For example, the Post and Business models can have several records of each other. Users can make several business adverts in their posts and vice versa.

However, creating many-to-many relationships can lead to inaccurate data. In other frameworks, you would have to create a new table to join the two tables.

Django has a solution for this. When you use the many-to-many field, It creates a new table mapping the two tables together. You can put the many-to-many field in either of the two models, but it shouldn’t be in both models.

        class Post(models.Model):
    title = models.CharField(max_length=120, null=True)
    post = models.TextField()
    date = models.DateTimeField(auto_now_add=True)
    user = models.ForeignKey(Profile, on_delete=models.CASCADE, related_name='post_owner')
    hood = models.ForeignKey(NeighbourHood, on_delete=models.CASCADE, related_name='hood_post')
    business = models.ManyToManyField(Business)
 
    def __str__(self):
        return f'{self.title} post'

Now, when you view the Post model on the admin panel, you can attach several businesses to one post.

Post model has option to add several businesses

Django Simplifies Database Relationships

The type of database you use for your application determines how to harness data. Django has a comprehensive system that makes connecting and operating relational databases easy.

Django features make it easy to store and retrieve data from related tables. It has in-built APIs that connect and create database relations for your app.

Database relationships determine the behavior of your application. Whether you use one-to-one, one-to-many, or many-to-many relationships depends on you.

With Django, you can configure and test features without breaking your application. Use Django to secure database systems and optimize your developer experience.