Creating Django Models (Database Tables)

Print

In Django, generally each model maps to a single database table.  Django gives us an automatically-generated database-access API. We use models.py file when creating our database tables and their relations like below.

In my example below, I have User, Department, Subdivision, Task and History tables for a Service Management application. This application will be used to create tasks for technicians. The tasks will be assigned to subdivisions first and then the users in that subdivision can take over that specific task. History table will be used for event logs which carried out for a specific task such as task created, task completed, task taken or task released etc. I also need department table, because dispatcher of a department should only create tasks for his own subdivisions. One last important thing is TheRequestOwner and The Technicians are both in the same table (User table). This is because the project I am working requires this. 

 

1. Department Model 

Remember, I already have a model for User which we abstracted previously. Now I will create a Department model and run migration commands right after it. Because default value of some Models fields will need to find a value  from Department.

Register my model to admin.py file to be able to see it on Admin Panel. Then add some Department records from admin panel.

l and I will add some records into it.

from django.db import models
from django.contrib.auth.models import AbstractUser

class Department(models.Model):
    name = models.CharField(max_length=50, blank=True, null=True)
    def __str__(self):
        return self.name

class User(AbstractUser):
    pass
    birthdate = models.DateField(blank=True, null=True)
    def __str__(self):
        return self.username

 

Run migration commands

python3 manage.py makemigrations
python3 manage.py migrate

 

 

 admin.py

First import Department model to admin.py and then register it. If you dont see this new model in Admin panel after registering it, just restart Apache service. It should shown up.

from django.contrib import admin
from django.contrib.auth import get_user_model
from django.contrib.auth.admin import UserAdmin
from .forms import UserCreationForm, UserChangeForm
from .models import User, Department

class UserAdmin(UserAdmin):
    add_form = UserCreationForm
    form = UserChangeForm
    model = User
    list_display = ['username', 'email', 'is_superuser', 'date_joined', 'birthdate', 'sex'] 
    admin.site.register(User, UserAdmin)
    admin.site.register(Department)

 

 

 Now I created 2 departments from admin panel.

 

2. Subdivision Model

The same thing should be done Subdivision also. Because default value of some other Models fields will need to find a value  from Subdivision. First create subdivision model and then run migration commands.

class SubDivision(models.Model):
    name = models.CharField(max_length=50, blank=True, null=True)
    department = models.ForeignKey('Department', default=3, related_name="sd_department", on_delete= models.CASCADE)
    email = models.EmailField(max_length=50, blank=True, null=True)
    def __str__(self):
        return self.name

 

python3 manage.py makemigrations
python3 manage.py migrate

 

I need to register my new model in admin.py to work on it from Admin Panel

admin.py

from django.contrib import admin
from django.contrib.auth import get_user_model
from django.contrib.auth.admin import UserAdmin
from .forms import UserCreationForm, UserChangeForm
from .models import User, Department, SubDivision

class UserAdmin(UserAdmin):
    add_form = UserCreationForm
    form = UserChangeForm
    model = User
    list_display = ['username', 'email', 'is_superuser', 'date_joined', 'birthdate'] 
    admin.site.register(User, UserAdmin)
    admin.site.register(Department)
    admin.site.register(SubDivision)

 

Now I create a few Subdivisions for both Information Technologies and Teknik departments.

 

 

 

Other Models:

Now I can create my other Models. I am creating these Models after Department and Subdivision Models are ready. I would get errors when creating these new Models because new Models have some fields that depend on Department and Subdivison Models. 

I can modify the User Model now like below. So, Users can have Departments and Subdivisions. Default value is 3 which is General.

class User(AbstractUser):
    pass
    birthdate = models.DateField(blank=True, null=True)
    department = models.ForeignKey('Department', default=3, related_name="user_department", on_delete=models.CASCADE)
    subdivision = models.ForeignKey('SubDivision', default=6, related_name="user_subdivision", on_delete=models.CASCADE)
    role = models.CharField(max_length=50, blank=True, null=True)
    sex= models.CharField(max_length=10, blank=True, null=True)
    def __str__(self):
        return self.username

 

 

 

This is the Task Model. created field will get its value (current time) automatically. For deadline I will use a date picker from which we can pick a date. taken field is a boolean field and I will use it if the task is taken by any technician or not.

I also want to put these records in the order of  their id. 

class Task(models.Model):
    subject = models.CharField(max_length=100)
    status = models.CharField(max_length=10)
    created = models.DateTimeField(auto_now=True)
    deadline = models.DateField(blank=True, null=True)
    assigned_sd = models.ForeignKey('SubDivision', default=3, related_name="assigned_sd", on_delete=models.PROTECT)
    assigned_department = models.ForeignKey('Department', default=3, related_name="assigned_department", on_delete=models.PROTECT)
    assigned_user = models.ForeignKey('User', default =1,  related_name="assigned_user", on_delete=models.PROTECT)
    createdby = models.ForeignKey('User', default =1, related_name="createdby", on_delete=models.PROTECT)
    request_owner = models.ForeignKey('User', default =1, related_name="request_owner", on_delete=models.PROTECT)
    taken = models.BooleanField(default=False)
    def __str__(self):
        return self.subject
    class Meta:
        ordering = ('id',)

 

Dont forget to register Task Model to admin.py.

 

 And my last models is History

class History(models.Model):
    event_log = models.CharField(max_length=100)
    event_date = models.DateTimeField(auto_now=True)
    task = models.ForeignKey('Task', blank=True, null=True, related_name="history_task", on_delete=models.CASCADE)
    department = models.ForeignKey('Department', blank=True, null=True,  related_name="history_department", on_delete=models.CASCADE)
    subdivision = models.ForeignKey('SubDivision', blank=True, null=True, related_name="history_subdivision", on_delete=models.CASCADE)
    user = models.ForeignKey('User', blank=True, null=True, related_name="history_user", on_delete=models.CASCADE)
    note = models.CharField(max_length=250, blank=True, null=True)
    def __str__(self):
        return self.event_log
    
    class Meta:
        ordering = ('id',)

 

Now we need to run migration commands again to create these models in our database.

python3 manage.py makemigrations
python3 manage.py migrate

 

 You can see the created tables (Models) by using PGAdmin.