🏠 Домашнее задание

🎯 Самопроверка Django-блока К оглавлению урока

Это не LMS-задание. Урок 25 — итоговое повторение Django-блока (уроки 13–24). В источнике (Summary session 5) разобраны три задания из LMS (уроки 22–24). Ниже представлена их полная формулировка с пошаговым решением.

LMS-задания блока (уроки 22–24)

Задание 1 (урок 22): CRUD операции в Django Shell

Выполнить запросы в Django Shell для модели Task и SubTask менеджера задач:

Задание 2 (урок 24): Инлайн-формы для Task

Подготовка окружения

1

Создание виртуального окружения

# PowerShell (Windows)
python -m venv venv
.\venv\Scripts\Activate.ps1

pip install django
pip freeze > requirements.txt
2

Создание проекта

django-admin startproject config .
python manage.py startapp task_manager
3

.gitignore и .env

# .gitignore
.env
*.pyc
__pycache__/
db.sqlite3
venv/

Пошаговое решение

4

models.py — Task, SubTask, Category

from django.db import models

class Category(models.Model):
    name = models.CharField(max_length=100, unique=True)

    def __str__(self):
        return self.name

    class Meta:
        db_table = 'task_manager_category'
        verbose_name = 'Category'
        unique_together = ('name',)


class Task(models.Model):
    STATUS_CHOICES = [
        ('New', 'New'),
        ('In progress', 'In progress'),
        ('Done', 'Done'),
    ]
    title = models.CharField(max_length=200)
    description = models.TextField(blank=True)
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='New')
    deadline = models.DateField(null=True, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    categories = models.ManyToManyField(Category, blank=True)

    def __str__(self):
        return self.title

    class Meta:
        db_table = 'task_manager_task'
        ordering = ['-created_at']
        verbose_name = 'Task'
        unique_together = ('title',)


class SubTask(models.Model):
    STATUS_CHOICES = [
        ('New', 'New'),
        ('In progress', 'In progress'),
        ('Done', 'Done'),
    ]
    title = models.CharField(max_length=200)
    description = models.TextField(blank=True)
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='New')
    deadline = models.DateField(null=True, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    task = models.ForeignKey(Task, on_delete=models.CASCADE, related_name='subtasks')

    def __str__(self):
        return self.title

    class Meta:
        db_table = 'task_manager_subtask'
        ordering = ['-created_at']
        verbose_name = 'SubTask'
        unique_together = ('title',)
5

admin.py — ModelAdmin, инлайны, action

from django.contrib import admin
from .models import Task, SubTask, Category


class SubTaskInline(admin.TabularInline):
    model = SubTask
    extra = 1
    fields = ('title', 'status', 'deadline')
    # verbose_name в поле выбора — полное, в списке — сокращённое через list_display


@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
    list_display = ('name',)
    search_fields = ('name',)


@admin.register(Task)
class TaskAdmin(admin.ModelAdmin):
    list_display = ('short_title', 'status', 'deadline', 'created_at')
    search_fields = ('title',)
    list_filter = ('status', 'categories')
    inlines = [SubTaskInline]

    def short_title(self, obj):
        """Выводить первые 10 символов, если название длиннее."""
        return obj.title[:10] + '...' if len(obj.title) > 10 else obj.title

    short_title.short_description = 'Title'


@admin.register(SubTask)
class SubTaskAdmin(admin.ModelAdmin):
    list_display = ('title', 'task', 'status', 'deadline')
    search_fields = ('title', 'task__title')
    list_filter = ('status',)
    actions = ['mark_done']

    @admin.action(description="Перевести в статус Done")
    def mark_done(self, request, queryset):
        queryset.update(status='Done')
6

Миграции и суперпользователь

python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser
7

Django Shell: CRUD для Task

python manage.py shell

from task_manager.models import Task, SubTask
from datetime import date, timedelta

# Создание Task
task = Task.objects.create(
    title="Prepare presentation",
    description="Prepare materials and slides for the presentation",
    status="New",
    deadline=date.today() + timedelta(days=3)
)

# Создание SubTask
sub1 = SubTask.objects.create(
    title="Gather information",
    description="Find necessary information for the presentation",
    status="New",
    deadline=date.today() + timedelta(days=2),
    task=task
)
sub2 = SubTask.objects.create(
    title="Create slides",
    description="Create presentation slides",
    status="New",
    deadline=date.today() + timedelta(days=1),
    task=task
)

# Чтение
new_tasks = Task.objects.filter(status="New")
print(new_tasks)

overdue_done_subtasks = SubTask.objects.filter(
    status="Done",
    deadline__lt=date.today()
)
print(overdue_done_subtasks)

# Изменение
task.status = "In progress"
task.save()

sub1.deadline = date.today() - timedelta(days=2)
sub1.save()

SubTask.objects.filter(title="Create slides").update(
    description="Create and format presentation slides"
)

# Удаление (каскадное из-за on_delete=CASCADE)
task.delete()

Проверка в VS Code

8

launch.json для Django

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Django",
            "type": "debugpy",
            "request": "launch",
            "program": "${workspaceFolder}/manage.py",
            "args": ["runserver"],
            "django": true,
            "justMyCode": true
        }
    ]
}

Нажмите F5 — сервер запустится с поддержкой точек останова. Откройте http://127.0.0.1:8000/admin/.

Критерии выполнения

Связь с разделами курса