Django — это мощный веб-фреймворк, написанный на языке Python. Он предоставляет разработчикам инструменты для быстрого создания безопасных и масштабируемых веб-приложений. В этой статье читатель познакомится с процессом установки Django и создания первого проекта.
Что такое Django и почему его стоит изучать?
Django — это высокоуровневый веб-фреймворк, который поощряет быструю разработку и чистый, прагматичный дизайн. Разработанный опытными программистами, Django заботится о многих аспектах веб-разработки, позволяя сосредоточиться на написании приложения без необходимости «изобретать велосипед».
- Быстрая разработка: Django предоставляет множество готовых компонентов для ускорения процесса разработки.
- Безопасность: Фреймворк включает в себя множество встроенных средств защиты от распространенных уязвимостей.
- Масштабируемость: Django способен обрабатывать трафик высокой нагрузки и может быть легко масштабирован.
- Универсальность: Подходит для разработки различных типов веб-приложений — от блогов до высоконагруженных веб-сайтов.
Подготовка к установке Django
Прежде чем приступить к установке Django, необходимо убедиться, что на компьютере установлен Python. Django совместим с Python 3.6 и выше.
Проверка наличия Python
Для проверки наличия Python и его версии следует открыть терминал (командную строку) и ввести следующую команду:
python --version
Если Python установлен, будет выведена его версия. Если команда не распознана, необходимо установить Python с официального сайта python.org.
Создание виртуального окружения
Рекомендуется использовать виртуальное окружение для изоляции проекта и его зависимостей. Для создания виртуального окружения выполняются следующие шаги:
- Открыть терминал и перейти в директорию, где будет располагаться проект.
- Выполнить команду для создания виртуального окружения:
python -m venv myenv
- Активировать виртуальное окружение:
- На Windows:
myenv\Scripts\activate
- На macOS и Linux:
source myenv/bin/activate
- На Windows:
Установка Django
После активации виртуального окружения можно приступить к установке Django. Процесс установки прост и выполняется с помощью pip — менеджера пакетов Python.
Установка последней версии Django
Для установки последней стабильной версии Django необходимо выполнить следующую команду:
pip install django
После завершения установки можно проверить версию установленного Django:
python -m django --version
Установка конкретной версии Django
Если требуется установить определенную версию Django, можно указать ее номер при установке:
pip install django==3.2.4
Это установит Django версии 3.2.4. Важно помнить, что разные версии могут иметь различия в функциональности и синтаксисе.
Создание первого проекта Django
После успешной установки Django можно приступить к созданию первого проекта. Django предоставляет удобную утилиту командной строки для автоматического создания базовой структуры проекта.
Использование django-admin для создания проекта
Для создания нового проекта выполняется следующая команда:
django-admin startproject myproject
Эта команда создаст новую директорию с именем «myproject», содержащую базовую структуру проекта Django.
Структура проекта Django
После выполнения команды будет создана следующая структура файлов и директорий:
myproject/ manage.py myproject/ __init__.py settings.py urls.py asgi.py wsgi.py
Каждый файл имеет свое назначение:
- manage.py: Утилита командной строки для взаимодействия с проектом.
- __init__.py: Пустой файл, указывающий Python, что эта директория является пакетом.
- settings.py: Файл настроек проекта.
- urls.py: Файл конфигурации URL-адресов проекта.
- asgi.py: Точка входа для ASGI-совместимых веб-серверов.
- wsgi.py: Точка входа для WSGI-совместимых веб-серверов.
Настройка базы данных
Django по умолчанию использует SQLite в качестве базы данных. Это упрощает начало работы, так как не требует дополнительной настройки. Однако для продакшн-проектов рекомендуется использовать более мощные СУБД, такие как PostgreSQL или MySQL.
Настройка базы данных в settings.py
Файл settings.py содержит настройки базы данных. По умолчанию он выглядит примерно так:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': BASE_DIR / 'db.sqlite3', } }
Эта конфигурация указывает Django использовать SQLite и создать файл базы данных db.sqlite3 в корневой директории проекта.
Применение миграций
После настройки базы данных необходимо применить миграции. Миграции — это способ Django обновлять схему базы данных в соответствии с изменениями в моделях. Для применения миграций выполняются следующие команды:
python manage.py migrate
Эта команда создаст необходимые таблицы в базе данных для встроенных приложений Django, таких как система аутентификации и сессий.
Создание первого приложения
Проект Django состоит из одного или нескольких приложений. Приложение — это модульная часть проекта, выполняющая определенную функцию. Для создания нового приложения используется команда startapp.
Использование manage.py для создания приложения
Чтобы создать новое приложение, необходимо выполнить следующую команду:
python manage.py startapp myapp
Эта команда создаст новую директорию «myapp» со следующей структурой:
myapp/ __init__.py admin.py apps.py migrations/ __init__.py models.py tests.py views.py
Регистрация приложения в проекте
После создания приложения его необходимо зарегистрировать в проекте. Для этого следует открыть файл settings.py и добавить имя приложения в список INSTALLED_APPS:
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'myapp', # Добавленная строка ]
Создание первого представления
Представление (view) в Django — это функция или класс, который обрабатывает HTTP-запрос и возвращает HTTP-ответ. Давайте создадим простое представление, которое будет выводить приветствие.
Написание функции представления
Откройте файл views.py в директории вашего приложения и добавьте следующий код:
from django.http import HttpResponse def hello_world(request): return HttpResponse("Привет, мир!")
Эта функция создает простой HTTP-ответ с текстом «Привет, мир!».
Настройка URL-маршрутизации
Чтобы связать созданное представление с URL, необходимо настроить маршрутизацию. Для этого создайте файл urls.py в директории вашего приложения и добавьте следующий код:
from django.urls import path from . import views urlpatterns = [ path('hello/', views.hello_world, name='hello_world'), ]
Затем откройте файл urls.py в директории проекта и добавьте ссылку на URL-конфигурацию приложения:
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('', include('myapp.urls')), ]
Запуск сервера разработки
Django поставляется с легким веб-сервером для разработки, который позволяет быстро тестировать приложение без необходимости настройки полноценного веб-сервера.
Команда для запуска сервера
Для запуска сервера разработки выполните следующую команду:
python manage.py runserver
По умолчанию сервер запустится на локальном хосте (127.0.0.1) и порту 8000.
Проверка работы приложения
После запуска сервера откройте веб-браузер и перейдите по адресу http://127.0.0.1:8000/hello/. Вы должны увидеть сообщение «Привет, мир!».
Основы работы с шаблонами Django
Шаблоны в Django позволяют отделить представление данных от логики приложения. Это делает код более чистым и легким для поддержки.
Создание первого шаблона
Создайте директорию templates в вашем приложении, а в ней файл hello.html со следующим содержимым:
<!DOCTYPE html> <html> <head> <title>Приветствие</title> </head> <body> <h1>{{ message }}</h1> </body> </html>
Использование шаблона в представлении
Измените функцию hello_world в файле views.py, чтобы использовать шаблон:
from django.shortcuts import render def hello_world(request): context = {'message': 'Привет, мир!'} return render(request, 'hello.html', context)
Работа с моделями данных
Модели в Django представляют структуру базы данных и позволяют работать с данными на уровне Python-объектов.
Создание простой модели
Откройте файл models.py в вашем приложении и добавьте следующий код:
from django.db import models class Task(models.Model): title = models.CharField(max_length=200) description = models.TextField(blank=True) created_at = models.DateTimeField(auto_now_add=True) def __str__(self): return self.title
Создание и применение миграций
После создания модели необходимо создать и применить миграции:
python manage.py makemigrations python manage.py migrate
Работа с административной панелью Django
Django предоставляет мощную административную панель, которая позволяет управлять данными приложения без написания дополнительного кода.
Регистрация модели в админ-панели
Откройте файл admin.py в вашем приложении и добавьте следующий код:
from django.contrib import admin from .models import Task admin.site.register(Task)
Создание суперпользователя
Для доступа к административной панели необходимо создать суперпользователя:
python manage.py createsuperuser
Следуйте инструкциям на экране, чтобы задать имя пользователя, email и пароль.
Обработка форм в Django
Формы играют важную роль в веб-приложениях, позволяя пользователям взаимодействовать с сервером.
Создание формы для модели
Создайте файл forms.py в директории вашего приложения и добавьте следующий код:
from django import forms from .models import Task class TaskForm(forms.ModelForm): class Meta: model = Task fields = ['title', 'description']
Использование формы в представлении
Измените файл views.py, чтобы использовать созданную форму:
from django.shortcuts import render, redirect from .forms import TaskForm from .models import Task def task_list(request): tasks = Task.objects.all() return render(request, 'task_list.html', {'tasks': tasks}) def task_create(request): if request.method == 'POST': form = TaskForm(request.POST) if form.is_valid(): form.save() return redirect('task_list') else: form = TaskForm() return render(request, 'task_form.html', {'form': form})
Создание шаблонов для отображения и создания задач
Теперь создадим шаблоны для отображения списка задач и формы создания новой задачи.
Шаблон списка задач
Создайте файл task_list.html в директории templates:
<!DOCTYPE html> <html> <head> <title>Список задач</title> </head> <body> <h1>Список задач</h1> <ul> {% for task in tasks %} <li>{{ task.title }} - {{ task.created_at }}</li> {% empty %} <li>Нет задач</li> {% endfor %} </ul> <a href="{% url 'task_create' %}">Создать новую задачу</a> </body> </html>
Шаблон формы создания задачи
Создайте файл task_form.html в директории templates:
<!DOCTYPE html> <html> <head> <title>Создание задачи</title> </head> <body> <h1>Создание новой задачи</h1> <form method="post"> {% csrf_token %} {{ form.as_p }} <button type="submit">Сохранить</button> </form> <a href="{% url 'task_list' %}">Вернуться к списку задач</a> </body> </html>
Настройка URL-маршрутов для новых представлений
Обновите файл urls.py в вашем приложении, чтобы добавить новые URL-маршруты:
from django.urls import path from . import views urlpatterns = [ path('', views.task_list, name='task_list'), path('create/', views.task_create, name='task_create'), ]
Добавление статических файлов
Статические файлы, такие как CSS и JavaScript, позволяют улучшить внешний вид и функциональность веб-приложения.
Настройка статических файлов
В файле settings.py убедитесь, что у вас есть следующие настройки:
STATIC_URL = '/static/' STATICFILES_DIRS = [ BASE_DIR / "static", ]
Создание CSS файла
Создайте директорию static в корне вашего проекта, а в ней файл style.css:
body { font-family: Arial, sans-serif; line-height: 1.6; margin: 0; padding: 20px; } h1 { color: #333; } ul { list-style-type: none; padding: 0; } li { background: #f4f4f4; margin-bottom: 10px; padding: 10px; border-radius: 5px; } a { color: #333; text-decoration: none; } a:hover { color: #666; } form { background: #f4f4f4; padding: 20px; border-radius: 5px; } button { background: #333; color: #fff; padding: 10px 15px; border: none; border-radius: 5px; cursor: pointer; } button:hover { background: #444; }
Подключение CSS к шаблонам
Обновите шаблоны task_list.html и task_form.html, добавив следующую строку в секцию <head>:
<link rel="stylesheet" href="{% static 'style.css' %}">
Также добавьте в начало файла:
{% load static %}
Добавление пагинации
При увеличении количества задач может потребоваться пагинация для улучшения производительности и удобства использования.
Обновление представления для поддержки пагинации
Измените функцию task_list в views.py:
from django.core.paginator import Paginator def task_list(request): tasks = Task.objects.all().order_by('-created_at') paginator = Paginator(tasks, 10) # 10 задач на страницу page_number = request.GET.get('page') page_obj = paginator.get_page(page_number) return render(request, 'task_list.html', {'page_obj': page_obj})
Обновление шаблона для отображения пагинации
Измените task_list.html, чтобы использовать пагинацию:
<ul> {% for task in page_obj %} <li>{{ task.title }} - {{ task.created_at }}</li> {% empty %} <li>Нет задач</li> {% endfor %} </ul> <div class="pagination"> <span class="step-links"> {% if page_obj.has_previous %} <a href="?page=1">« первая</a> <a href="?page={{ page_obj.previous_page_number }}">предыдущая</a> {% endif %} <span class="current"> Страница {{ page_obj.number }} из {{ page_obj.paginator.num_pages }}. </span> {% if page_obj.has_next %} <a href="?page={{ page_obj.next_page_number }}">следующая</a> <a href="?page={{ page_obj.paginator.num_pages }}">последняя »</a> {% endif %} </span> </div>
Добавление функциональности поиска
Поиск поможет пользователям быстро находить нужные задачи.
Обновление представления для поддержки поиска
Измените функцию task_list в views.py:
from django.db.models import Q def task_list(request): query = request.GET.get('q') if query: tasks = Task.objects.filter(Q(title__icontains=query) | Q(description__icontains=query)) else: tasks = Task.objects.all() tasks = tasks.order_by('-created_at') paginator = Paginator(tasks, 10) page_number = request.GET.get('page') page_obj = paginator.get_page(page_number) return render(request, 'task_list.html', {'page_obj': page_obj, 'query': query})
Добавление формы поиска в шаблон
Добавьте следующий код в начало task_list.html:
<form method="get" action="{% url 'task_list' %}"> <input type="text" name="q" value="{{ query|default:'' }}" placeholder="Поиск задач"> <button type="submit">Поиск</button> </form>
Добавление аутентификации пользователей
Аутентификация позволит ограничить доступ к созданию и редактированию задач только для зарегистрированных пользователей.
Создание представлений для регистрации и входа
Добавьте следующие функции в views.py:
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm from django.contrib.auth import login, logout from django.contrib.auth.decorators import login_required def register(request): if request.method == 'POST': form = UserCreationForm(request.POST) if form.is_valid(): user = form.save() login(request, user) return redirect('task_list') else: form = UserCreationForm() return render(request, 'register.html', {'form': form}) def user_login(request): if request.method == 'POST': form = AuthenticationForm(data=request.POST) if form.is_valid(): user = form.get_user() login(request, user) return redirect('task_list') else: form = AuthenticationForm() return render(request, 'login.html', {'form': form}) def user_logout(request): logout(request) return redirect('task_list') @login_required def task_create(request): # Существующий код функции task_create
Создание шаблонов для регистрации и входа
Создайте файлы register.html и login.html в директории templates:
<!-- register.html --> <h2>Регистрация</h2> <form method="post"> {% csrf_token %} {{ form.as_p }} <button type="submit">Зарегистрироваться</button> </form> <!-- login.html --> <h2>Вход</h2> <form method="post"> {% csrf_token %} {{ form.as_p }} <button type="submit">Войти</button> </form>
Обновление URL-маршрутов
Добавьте новые URL-маршруты в urls.py:
from django.urls import path from . import views urlpatterns = [ path('', views.task_list, name='task_list'), path('create/', views.task_create, name='task_create'), path('register/', views.register, name='register'), path('login/', views.user_login, name='login'), path('logout/', views.user_logout, name='logout'), ]
Добавление возможности редактирования и удаления задач
Для полноценного управления задачами добавим функциональность редактирования и удаления.
Создание представлений для редактирования и удаления
Добавьте следующие функции в views.py:
from django.shortcuts import get_object_or_404 @login_required def task_edit(request, pk): task = get_object_or_404(Task, pk=pk) if request.method == 'POST': form = TaskForm(request.POST, instance=task) if form.is_valid(): form.save() return redirect('task_list') else: form = TaskForm(instance=task) return render(request, 'task_form.html', {'form': form}) @login_required def task_delete(request, pk): task = get_object_or_404(Task, pk=pk) if request.method == 'POST': task.delete() return redirect('task_list') return render(request, 'task_confirm_delete.html', {'task': task})
Создание шаблона для подтверждения удаления
Создайте файл task_confirm_delete.html в директории templates:
<h2>Подтверждение удаления</h2> <p>Вы уверены, что хотите удалить задачу "{{ task.title }}"?</p> <form method="post"> {% csrf_token %} <button type="submit">Да, удалить</button> </form> <a href="{% url 'task_list' %}">Отмена</a>
Обновление URL-маршрутов
Добавьте новые URL-маршруты в urls.py:
path('edit/<int:pk>/', views.task_edit, name='task_edit'), path('delete/<int:pk>/', views.task_delete, name='task_delete'),
Обновление шаблона списка задач
Измените task_list.html, чтобы добавить ссылки на редактирование и удаление:
<ul> {% for task in page_obj %} <li> {{ task.title }} - {{ task.created_at }} <a href="{% url 'task_edit' task.pk %}">Редактировать</a> <a href="{% url 'task_delete' task.pk %}">Удалить</a> </li> {% empty %} <li>Нет задач</li> {% endfor %} </ul>
Добавление категорий для задач
Категории помогут организовать задачи и улучшить навигацию.
Создание модели категории
Добавьте следующий код в models.py:
class Category(models.Model): name = models.CharField(max_length=100) def __str__(self): return self.name class Task(models.Model): # Существующие поля category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True, blank=True)
Обновление формы задачи
Измените TaskForm в forms.py, чтобы включить поле категории:
class TaskForm(forms.ModelForm): class Meta: model = Task fields = ['title', 'description', 'category']
Создание представления для списка категорий
Добавьте следующую функцию в views.py:
def category_list(request): categories = Category.objects.all() return render(request, 'category_list.html', {'categories': categories})
Создание шаблона для списка категорий
Создайте файл category_list.html в директории templates:
<h2>Категории</h2> <ul> {% for category in categories %} <li> <a href="{% url 'task_list' %}?category={{ category.pk }}">{{ category.name }}</a> </li> {% empty %} <li>Нет категорий</li> {% endfor %} </ul>
Обновление представления списка задач
Измените функцию task_list в views.py, чтобы учитывать фильтрацию по категориям:
def task_list(request): query = request.GET.get('q') category_id = request.GET.get('category') tasks = Task.objects.all() if query: tasks = tasks.filter(Q(title__icontains=query) | Q(description__icontains=query)) if category_id: tasks = tasks.filter(category_id=category_id) tasks = tasks.order_by('-created_at') paginator = Paginator(tasks, 10) page_number = request.GET.get('page') page_obj = paginator.get_page(page_number) categories = Category.objects.all() return render(request, 'task_list.html', { 'page_obj': page_obj, 'query': query, 'categories': categories, 'selected_category': category_id })
Обновление шаблона списка задач
Добавьте список категорий в task_list.html:
<h3>Категории</h3> <ul> <li><a href="{% url 'task_list' %}">Все задачи</a></li> {% for category in categories %} <li> <a href="{% url 'task_list' %}?category={{ category.pk }}" {% if selected_category == category.pk|stringformat:"s" %}class="selected"{% endif %}> {{ category.name }} </a> </li> {% endfor %} </ul>
Добавление приоритетов для задач
Приоритеты помогут пользователям выделять наиболее важные задачи.
Обновление модели задачи
Добавьте поле приоритета в модель Task в models.py:
class Task(models.Model): PRIORITY_CHOICES = ( (1, 'Низкий'), (2, 'Средний'), (3, 'Высокий'), ) # Существующие поля priority = models.IntegerField(choices=PRIORITY_CHOICES, default=2)
Обновление формы задачи
Добавьте поле приоритета в TaskForm в forms.py:
class TaskForm(forms.ModelForm): class Meta: model = Task fields = ['title', 'description', 'category', 'priority']
Обновление представления списка задач
Измените функцию task_list в views.py, чтобы учитывать сортировку по приоритету:
def task_list(request): # Существующий код sort = request.GET.get('sort', '-created_at') if sort == 'priority': tasks = tasks.order_by('-priority', '-created_at') else: tasks = tasks.order_by(sort) # Остальной код
Обновление шаблона списка задач
Добавьте возможность сортировки по приоритету в task_list.html:
<p> Сортировать по: <a href="{% url 'task_list' %}?sort=-created_at">Дате создания</a> | <a href="{% url 'task_list' %}?sort=priority">Приоритету</a> </p> <ul> {% for task in page_obj %} <li> {{ task.title }} - {{ task.get_priority_display }} приоритет <!-- Остальной код --> </li> {% empty %} <li>Нет задач</li> {% endfor %} </ul>
Добавление дат выполнения для задач
Даты выполнения помогут пользователям отслеживать сроки выполнения задач.
Обновление модели задачи
Добавьте поле даты выполнения в модель Task в models.py:
from django.utils import timezone class Task(models.Model): # Существующие поля due_date = models.DateField(null=True, blank=True) def is_overdue(self): return self.due_date and self.due_date < timezone.now().date()
Обновление формы задачи
Добавьте поле даты выполнения в TaskForm в forms.py:
class TaskForm(forms.ModelForm): due_date = forms.DateField( widget=forms.DateInput(attrs={'type': 'date'}), required=False ) class Meta: model = Task fields = ['title', 'description', 'category', 'priority', 'due_date']
Обновление представления списка задач
Измените функцию task_list в views.py, чтобы учитывать фильтрацию по статусу выполнения:
def task_list(request): # Существующий код status = request.GET.get('status') if status == 'overdue': tasks = tasks.filter(due_date__lt=timezone.now().date()) elif status == 'upcoming': tasks = tasks.filter(due_date__gte=timezone.now().date()) # Остальной код
Обновление шаблона списка задач
Добавьте фильтрацию по статусу выполнения в task_list.html:
<p> Фильтр: <a href="{% url 'task_list' %}">Все задачи</a> | <a href="{% url 'task_list' %}?status=overdue">Просроченные</a> | <a href="{% url 'task_list' %}?status=upcoming">Предстоящие</a> </p> <ul> {% for task in page_obj %} <li{% if task.is_overdue %} class="overdue"{% endif %}> {{ task.title }} - {{ task.get_priority_display }} приоритет {% if task.due_date %} - Срок: {{ task.due_date }} {% endif %} <!-- Остальной код --> </li> {% empty %} <li>Нет задач</li> {% endfor %} </ul>
Добавление комментариев к задачам
Комментарии позволят пользователям обсуждать задачи и добавлять дополнительную информацию.
Создание модели комментария
Добавьте следующий код в models.py:
class Comment(models.Model): task = models.ForeignKey(Task, on_delete=models.CASCADE, related_name='comments') author = models.ForeignKey(User, on_delete=models.CASCADE) text = models.TextField() created_at = models.DateTimeField(auto_now_add=True) def __str__(self): return f'Comment by {self.author} on {self.task}'
Создание формы комментария
Добавьте следующий код в forms.py:
class CommentForm(forms.ModelForm): class Meta: model = Comment fields = ['text']
Создание представления для добавления комментария
Добавьте следующую функцию в views.py:
@login_required def add_comment(request, task_id): task = get_object_or_404(Task, id=task_id) if request.method == 'POST': form = CommentForm(request.POST) if form.is_valid(): comment = form.save(commit=False) comment.task = task comment.author = request.user comment.save() return redirect('task_detail', pk=task.pk) else: form = CommentForm() return render(request, 'add_comment.html', {'form': form, 'task': task})
Создание шаблона для добавления комментария
Создайте файл add_comment.html в директории templates:
<h2>Добавить комментарий к задаче "{{ task.title }}"</h2> <form method="post"> {% csrf_token %} {{ form.as_p }} <button type="submit">Добавить комментарий</button> </form> <a href="{% url 'task_detail' task.pk %}">Вернуться к задаче</a>
Обновление представления детальной информации о задаче
Добавьте следующую функцию в views.py:
def task_detail(request, pk): task = get_object_or_404(Task, pk=pk) comments = task.comments.all().order_by('-created_at') comment_form = CommentForm() return render(request, 'task_detail.html', { 'task': task, 'comments': comments, 'comment_form': comment_form })
Создание шаблона для детальной информации о задаче
Создайте файл task_detail.html в директории templates:
<h2>{{ task.title }}</h2> <p>{{ task.description }}</p> <p>Приоритет: {{ task.get_priority_display }}</p> {% if task.category %} <p>Категория: {{ task.category }}</p> {% endif %} {% if task.due_date %} <p>Срок выполнения: {{ task.due_date }}{% if task.is_overdue %} (просрочено){% endif %}</p> {% endif %} <h3>Комментарии</h3> {% for comment in comments %} <div> <p>{{ comment.text }}</p> <p>Автор: {{ comment.author }} | {{ comment.created_at }}</p> </div> {% empty %} <p>Нет комментариев</p> {% endfor %} <h4>Добавить комментарий</h4> <form method="post" action="{% url 'add_comment' task.pk %}"> {% csrf_token %} {{ comment_form.as_p }} <button type="submit">Добавить комментарий</button> </form> <a href="{% url 'task_list' %}">Вернуться к списку задач</a>
Обновление URL-маршрутов
Добавьте новые URL-маршруты в urls.py:
path('task/<int:pk>/', views.task_detail, name='task_detail'), path('task/<int:task_id>/comment/', views.add_comment, name='add_comment'),
Добавление функции поиска по нескольким полям
Расширенный поиск позволит пользователям находить задачи по различным критериям.
Создание формы расширенного поиска
Добавьте следующий код в forms.py:
class AdvancedSearchForm(forms.Form): query = forms.CharField(required=False, label='Поиск') category = forms.ModelChoiceField(queryset=Category.objects.all(), required=False, label='Категория') priority = forms.ChoiceField(choices=[('', '---')] + Task.PRIORITY_CHOICES, required=False, label='Приоритет') status = forms.ChoiceField(choices=[ ('', '---'), ('overdue', 'Просроченные'), ('upcoming', 'Предстоящие'), ], required=False, label='Статус') start_date = forms.DateField(required=False, widget=forms.DateInput(attrs={'type': 'date'}), label='С даты') end_date = forms.DateField(required=False, widget=forms.DateInput(attrs={'type': 'date'}), label='По дату')
Обновление представления списка задач
Измените функцию task_list в views.py, чтобы использовать форму расширенного поиска:
from django.db.models import Q def task_list(request): form = AdvancedSearchForm(request.GET) tasks = Task.objects.all() if form.is_valid(): query = form.cleaned_data.get('query') category = form.cleaned_data.get('category') priority = form.cleaned_data.get('priority') status = form.cleaned_data.get('status') start_date = form.cleaned_data.get('start_date') end_date = form.cleaned_data.get('end_date') if query: tasks = tasks.filter(Q(title__icontains=query) | Q(description__icontains=query)) if category: tasks = tasks.filter(category=category) if priority: tasks = tasks.filter(priority=priority) if status == 'overdue': tasks = tasks.filter(due_date__lt=timezone.now().date()) elif status == 'upcoming': tasks = tasks.filter(due_date__gte=timezone.now().date()) if start_date: tasks = tasks.filter(due_date__gte=start_date) if end_date: tasks = tasks.filter(due_date__lte=end_date) tasks = tasks.order_by('-created_at') paginator = Paginator(tasks, 10) page_number = request.GET.get('page') page_obj = paginator.get_page(page_number) return render(request, 'task_list.html', { 'page_obj': page_obj, 'form': form })
Обновление шаблона списка задач
Измените task_list.html, чтобы включить форму расширенного поиска:
<h2>Расширенный поиск</h2> <form method="get"> {{ form.as_p }} <button type="submit">Поиск</button> </form> <h2>Список задач</h2> <!-- Существующий код для отображения списка задач -->
Добавление функции экспорта задач
Экспорт задач позволит пользователям сохранять свои задачи в различных форматах.
Создание функции экспорта в CSV
Добавьте следующую функцию в views.py:
import csv from django.http import HttpResponse def export_tasks_csv(request): response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = 'attachment; filename="tasks.csv"' writer = csv.writer(response) writer.writerow(['Title', 'Description', 'Category', 'Priority', 'Due Date', 'Created At']) tasks = Task.objects.all().values_list('title', 'description', 'category__name', 'priority', 'due_date', 'created_at') for task in tasks: writer.writerow(task) return response
Добавление URL-маршрута для экспорта
Добавьте следующий маршрут в urls.py:
path('export/csv/', views.export_tasks_csv, name='export_tasks_csv'),
Добавление ссылки на экспорт в шаблон списка задач
Добавьте следующий код в task_list.html:
<a href="{% url 'export_tasks_csv' %}">Экспорт задач в CSV</a>
Добавление функции импорта задач
Импорт задач позволит пользователям загружать задачи из файлов.
Создание формы для импорта CSV
Добавьте следующий код в forms.py:
class ImportCSVForm(forms.Form): csv_file = forms.FileField(label='Выберите CSV файл')
Создание функции импорта из CSV
Добавьте следующую функцию в views.py:
import csv import io from django.contrib import messages @login_required def import_tasks_csv(request): if request.method == 'POST': form = ImportCSVForm(request.POST, request.FILES) if form.is_valid(): csv_file = request.FILES['csv_file'] decoded_file = csv_file.read().decode('utf-8') io_string = io.StringIO(decoded_file) next(io_string) # Пропускаем заголовок for row in csv.reader(io_string, delimiter=',', quotechar='"'): _, created = Task.objects.get_or_create( title=row[0], description=row[1], category=Category.objects.get_or_create(name=row[2])[0], priority=row[3], due_date=row[4] if row[4] else None, ) messages.success(request, 'Задачи успешно импортированы') return redirect('task_list') else: form = ImportCSVForm() return render(request, 'import_tasks.html', {'form': form})
Создание шаблона для импорта задач
Создайте файл import_tasks.html в директории templates:
<h2>Импорт задач из CSV</h2> <form method="post" enctype="multipart/form-data"> {% csrf_token %} {{ form.as_p }} <button type="submit">Импортировать</button> </form> <a href="{% url 'task_list' %}">Вернуться к списку задач</a>
Добавление URL-маршрута для импорта
Добавьте следующий маршрут в urls.py:
path('import/csv/', views.import_tasks_csv, name='import_tasks_csv'),
Добавление ссылки на импорт в шаблон списка задач
Добавьте следующий код в task_list.html:
<a href="{% url 'import_tasks_csv' %}">Импорт задач из CSV</a>
Добавление уведомлений о предстоящих задачах
Уведомления помогут пользователям не забывать о важных задачах.
Создание модели уведомления
Добавьте следующий код в models.py:
class Notification(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) task = models.ForeignKey(Task, on_delete=models.CASCADE) created_at = models.DateTimeField(auto_now_add=True) is_read = models.BooleanField(default=False) def __str__(self): return f'Уведомление для {self.user} о задаче {self.task}'
Создание функции для генерации уведомлений
Добавьте следующую функцию в views.py:
from django.utils import timezone def generate_notifications(): tomorrow = timezone.now().date() + timezone.timedelta(days=1) tasks = Task.objects.filter(due_date=tomorrow) for task in tasks: Notification.objects.get_or_create(user=task.user, task=task)
Настройка регулярного выполнения генерации уведомлений
Для регулярного выполнения генерации уведомлений можно использовать Celery или Django-crontab. Например, с использованием Django-crontab добавьте следующий код в settings.py:
INSTALLED_APPS = [ # ... 'django_crontab', ] CRONJOBS = [ ('0 0 * * *', 'your_app.views.generate_notifications') ]
Отображение уведомлений
Добавьте следующую функцию в views.py для отображения уведомлений:
@login_required def notifications(request): notifications = Notification.objects.filter(user=request.user, is_read=False) return render(request, 'notifications.html', {'notifications': notifications})
Создание шаблона для отображения уведомлений
Создайте файл notifications.html в директории templates:
<h2>Уведомления</h2> <ul> {% for notification in notifications %} <li> Задача "{{ notification.task.title }}" должна быть выполнена завтра <a href="{% url 'task_detail' notification.task.pk %}">Перейти к задаче</a> </li> {% empty %} <li>Нет новых уведомлений</li> {% endfor %} </ul> <a href="{% url 'task_list' %}">Вернуться к списку задач</a>
Добавление URL-маршрута для уведомлений
Добавьте следующий маршрут в urls.py:
path('notifications/', views.notifications, name='notifications'),
Добавление ссылки на уведомления в базовый шаблон
Добавьте следующий код в ваш базовый шаблон (обычно base.html):
{% if user.is_authenticated %} <a href="{% url 'notifications' %}">Уведомления ({{ user.notification_set.filter(is_read=False).count }})
Заключение
В этой статье мы рассмотрели процесс создания функционального приложения для управления задачами с использованием Django. Мы охватили следующие темы:
- Установка Django и создание проекта