Skip to content
This repository has been archived by the owner on Jul 2, 2024. It is now read-only.

Add task model

Serhii Horodilov edited this page Feb 20, 2024 · 6 revisions

At the end of this guide you will:

  • create a Django model to represent tasks
  • create and apply migrations to the project database
Make sure you have successful configured PostgreSQL database before you begin.

Table of Contents

Getting started

git checkout bp-models-tasks

Task model UML diagram

erDiagram
    task {
        UUID uuid "primary key"
        string summary
        string description
        bool completed
        datetime created_at
        datetime updated_at
        bigint reporter "foreign key"
        bigint assignee "foreign key"
    }
Loading

Guide

Create task model

# tasks/models.py
"""
Tasks application models

"""

import uuid

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

UserModel = get_user_model()


class TaskModel(models.Model):
    """
    Task model implementation

    :ivar uuid: primary key
    :type uuid: :class: `uuid.UUID`
    :ivar summary: title, or short description (up to 128 characters).
    :type summary: str
    :ivar description: detailed description, defaults to None.
    :type description: str
    :ivar completed: completed status, defaults to False.
    :type completed: bool
    :ivar created_at: created timestamp, non-editable.
    :type created_at: :class: `datetime.datetime`
    :ivar updated_at: updated timestamp, non-editable.
    :type updated_at: :class: `datetime.datetime`
    :ivar assignee: reference to a user that task is assigned to.
    :type assignee: :class: `UserModel`, optional
    :ivar reporter: reference to a user that created the task.
    :type reporter: :class: `UserModel`

    Represents a tasks registered in the system.
    Each new task is created as uncompleted by default.
    Each task gets its ``created_at`` timestamp once on task creation.
    Each task updates its ``updated_at`` timestamp on each task save.

    """

    uuid = models.UUIDField(
        default=uuid.uuid4,
        editable=False,
        primary_key=True,
        verbose_name="primary key",
    )

    summary = models.CharField(
        max_length=128,
        help_text="Required. 128 characters or fewer."
    )
    description = models.TextField(
        blank=True,
        default="",
    )
    completed = models.BooleanField(
        default=False,
        verbose_name="completed status"
    )

    # task metadata
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    # relationships
    assignee = models.ForeignKey(
        UserModel,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="tasks_assigned",
        verbose_name="assigned to",
    )
    reporter = models.ForeignKey(
        UserModel,
        on_delete=models.PROTECT,
        related_name="tasks_reported",
        verbose_name="reported by",
    )

    @property
    def title(self) -> str:
        return str(self)

    def __str__(self) -> str:
        """Return a string version of an instance"""

        return self.summary

Create initial migration

python manage.py makemigrations

A new python module will be created in tasks/migrations. In case no new migrations appear, lurk for Troubleshooting#no-migrations.

Understanding migrations

Migrations are Django's way of propagating changes you make to your models (adding a field, deleting a model, etc.) into your database schema. They're designed to be mostly automatic, but you'll need to know when to make migrations, when to run them, and the common problems you might run into.

By default initial migration is created with name 0001_initial.py; this can be modified by using --name option within makemigrations command.

See also.

Apply migrations

python manage.py migrate

Register task model to admin site

See also.

# tasks/admin.py
"""
Tasks application admin site
"""

from typing import Union

from django.contrib import admin

from tasks.models import TaskModel


@admin.register(TaskModel)
class TaskModelAdmin(admin.ModelAdmin):
    """
    Task model administration
    """

    list_display = ("summary", "completed", "get_reporter", "get_assignee")
    list_display_links = ("summary",)
    list_filter = ("reporter", "assignee", "completed")
    list_per_page = 20
    readonly_fields = ("uuid",)

    @admin.display(description="assigned to")
    def get_assignee(self, obj: TaskModel) -> Union[str, None]:
        if obj.assignee is None:
            return

        return obj.assignee.get_full_name() or obj.assignee.username

    @admin.display(description="reported by")
    def get_reporter(self, obj: TaskModel) -> str:
        return obj.reporter.get_full_name() or obj.reporter.username

Register superuser to access the Django admin site

You will need a superuser to obtain the access to the admin site.

python manage.py createsuperuser

Use whatever username and password, this user will be flushed in the future, once the custom user model will be implemented.

Test the model via admin site

Navigate to http://localhost:8000/admin/ and authenticate using the credentials of the superuser created at previous step. You should be able to interact with the task model via admin site.

Changes

  1. Full change log