🏠 Домашнее задание
Это не LMS-задание. Урок 25 — итоговое повторение Django-блока (уроки 13–24). В источнике (Summary session 5) разобраны три задания из LMS (уроки 22–24). Ниже представлена их полная формулировка с пошаговым решением.
LMS-задания блока (уроки 22–24)
Задание 1 (урок 22): CRUD операции в Django Shell
Выполнить запросы в Django Shell для модели Task и SubTask менеджера задач:
- Создание Task: title="Prepare presentation", description="Prepare materials and slides", status="New", deadline=сегодня + 3 дня.
- Создание SubTask: "Gather information" (deadline + 2 дня) и "Create slides" (deadline + 1 день), оба со статусом New, связаны с Task выше.
- Чтение: все Task со статусом "New"; все SubTask со статусом "Done" у которых дедлайн истёк.
- Изменение: статус "Prepare presentation" → "In progress"; дедлайн "Gather information" → 2 дня назад; описание "Create slides" → "Create and format presentation slides".
- Удаление: удалить Task "Prepare presentation" и все её подзадачи.
Задание 2 (урок 24): Инлайн-формы для Task
- Добавить TabularInline для SubTask на страницу Task в admin.
- В списке задач выводить первые 10 символов названия + "..." если длиннее. При выборе Task для SubTask — полное название.
- Реализовать action для SubTask: перевести выбранные в статус "Done".
Подготовка окружения
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/.
Критерии выполнения
- Три модели (Task, SubTask, Category) с __str__ и Meta (db_table, ordering, verbose_name)
- ForeignKey SubTask → Task с CASCADE; ManyToManyField Task → Category
- Admin: TaskAdmin с short_title, SubTaskInline (TabularInline), action mark_done для SubTask
- Все CRUD-запросы в Django Shell выполняются без ошибок
- Миграции применены без конфликтов
Связь с разделами курса
- Метод __str__ и класс Meta: theory.html#str-meta
- Admin и инлайны: theory.html#admin, theory.html#inline
- ORM-запросы: theory.html#orm
- Примеры кода: examples.html
- Частые ошибки: mistakes.html