In Part I, we learnt about the basic request and response flow in Django.
However, I find it easier to have a hands-on approach with a custom setup as the target, so that you understand it faster instead of blindly following instructions. Let us define a problem statement for that.
Problem
Say you want to track all your tasks for the day. In order to do that, what would you be needing?
- Definitely a task id (you know, to keep track of it)
- A task title
- A task description
- Status of the task
- Priority of the task
These are the bare minimum that you need to track a task. So we can create a web application that opens up to a page with list of tasks and the option to add a task. Clicking on any task should be able to take you to a page with that task details.
Creating the app
Quickly, to start, let us create an app. So we do something like -
# create the project
django-admin startproject board
cd board
# from this point on, we will use python manage.py
python manage.py startapp taskboard
So we've got our taskboard app. The next part is to define our model.
(A lot of tutorials would have you writing the 'Hello world' view first. I'd prefer we get our hands dirty from the beginning itself ;)
What exactly is a model? It's a class (or classes) with a bunch of attributes (see problem section above) and methods that define the data you'd be storing in your app.
Defining the model
So, in our taskboard/models.py, we define our model.
from django.db import models
from django.core.validators import MaxValueValidator, MinValueValidator
from django.utils.translation import gettext_lazy as _
class Group(models.Model):
group_id = models.AutoField(primary_key=True)
group_title = models.CharField(max_length=100)
group_status = models.IntegerField(default=1,
validators=[MaxValueValidator(3), MinValueValidator(1)])
class Task(models.Model):
class Priority(models.IntegerChoices):
LOW = 1, _('Low')
MEDIUM = 2, _('Medium')
HIGH = 3, _('High')
class Status(models.IntegerChoices):
NEW = 1, _('New')
IN_PROGRESS = 2, _('In Progress')
RESOLVED = 3, _('Finished')
def get_priority(self):
return self.Priority(self.task_priority).label
def get_status(self):
return self.Status(self.task_status).label
task_group = models.ForeignKey(Group, on_delete=models.CASCADE)
task_id = models.AutoField(primary_key=True)
task_title = models.CharField(max_length=100)
task_description = models.CharField(max_length=1000)
task_priority = models.IntegerField(default=1, choices=Priority.choices)
task_status = models.IntegerField(default=1, choices=Status.choices)
Let's see what this is. We have defined a group too (irrelevant for now, each task will have one group, its a one-to-one schema, we will modify it to many-to-one later) just for convenience (so that at a point we get to see all related tasks bundled together).
The primary_key=True tag makes sure the corresponding attribute is auto-incrementing and unique. Each of the attributes are some kind of fields. The validators would be used when you will take in the values via some form for validating the inputs. Think of it as a way of restricting your inputs.
Another way of restricting your inputs and having a label against each of them can be done using the choice field. We use a nested class inside Task here since it makes sense (so that tasks can have different statuses and priorities), and we allocate 3 different labels to status and priority each. The _('New')_ is for getting the label in get_status(self) and those methods, when it is requested from the webpage.
Tell Django you have an app
The next part is a one-time step. You need to let Django know that you have defined an app and you want to use it. So, just go to board/settings.py, and in the INSTALLED_APPS link, add the first entry as taskboard.apps.TaskboardConfig, so it looks like -
INSTALLED_APPS = [
'taskboard.apps.TaskboardConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
Notice the format, <appname>.apps.<Capitalizedappname>Config.
Now Django knows you have some app called Taskboard defined. The next part is to actually create the database where it can store the data (so far we have only defined the model).
Run python manage.py makemigrations taskboard. This lets Django know you changed your model. You need to run this command every time you change the model.
The next part is again one-time (Creating the .db file).
Run python manage.py sqlmigrations taskboard 0001. This will create the .db file in SQLite. (0001 is the first version.)
And finally, apply the changes Django has seen in the makemigrations command to the database. Command is python manage.py migrate.
From now, every time you change the model -
python manage.py makemigrations taskboard
python manage.py migrate
These two commands will update your database schema.
Finally, you need to get your database admin role. So, type inpython manage.py createsuperuserand fill in the fields.
You can see the admin page at http://127.0.0.1:8000/admin/. If you want to see the models (i.e. Group and Task) in admin interface, go to taskboard/admin.py and put the following content in there :
from .models import Group, Task
admin.site.register(Group)
admin.site.register(Task)
That's it! Your backend is all done and set up. In the next part, we'll see how to properly set up the front-end of our app.