⚖️ Старый vs Новый: Django ORM

Устаревшие паттерны из лекции → современный Django 5.x

⚡ Главные различия

  • datetime import: from django.db.models.functions.datetime import datetimeimport datetime; timezone.make_aware(...)
  • timezone.datetime().astimezone():timezone.make_aware(datetime.datetime(...))
  • User.objects.create():User.objects.create_user() для корректного хэширования пароля
  • Опечатка в лекции: task_to_updated.update()task_to_update.update()

← К оглавлению урока

1. Импорт datetime для timezone-aware дат

Из лекции (старое / нестандартное)

# Нестандартный импорт из внутренних модулей Django
from django.db.models.functions.datetime import datetime

date = datetime(year=2024, month=6, day=30)
return date.astimezone()

Современный подход (Django 5.x)

import datetime
from django.utils import timezone

date = datetime.datetime(year=2024, month=6, day=30)
return timezone.make_aware(date)  # явное создание timezone-aware объекта
⚠️ Проверить по документации: django.db.models.functions.datetime предназначен для использования в аннотациях/запросах, а не для создания Python-объектов datetime. В Django 5.x рекомендуется стандартный import datetime.

2. timezone.datetime().astimezone() → make_aware()

Из лекции (старое)

from django.utils import timezone

required_date = timezone.datetime(2023, 1, 1).astimezone()
# timezone.datetime — алиас для datetime.datetime (зависит от версии)

Современный подход (Django 5.x)

import datetime
from django.utils import timezone

required_date = timezone.make_aware(datetime.datetime(2023, 1, 1))
# make_aware() правильно присваивает текущий timezone из настроек TIME_ZONE

3. Создание пользователей: create() vs create_user()

Из лекции (небезопасно)

from django.contrib.auth.models import User

# Пароль сохраняется в открытом виде — НЕ делайте так в production
backend_dev = User.objects.create(
    username='backend_dev',
    password='sd7f6g5fsfd',
    email='backend.dev@gmail.com'
)

Современный подход (Django 5.x)

from django.contrib.auth.models import User

# create_user() автоматически хэширует пароль
backend_dev = User.objects.create_user(
    username='backend_dev',
    password='sd7f6g5fsfd',
    email='backend.dev@gmail.com'
)
Важно: User.objects.create(password=...) сохраняет пароль в открытом виде. В Django 5.x для создания пользователей с паролём используйте create_user(), который вызывает set_password() внутри.

4. Опечатка в лекции: имя переменной

Из лекции (опечатка)

task_to_update = Task.objects.filter(name='Update schema')
task_to_updated.update(status='pending')  # NameError: task_to_updated не существует

Исправленный вариант

task_to_update = Task.objects.filter(name='Update schema')
task_to_update.update(status='pending')  # правильно

5. Фильтрация задач по конкретному месяцу (Задание 16)

Из лекции (может не работать)

from django.db.models import F

# F('created_date__month') — синтаксис для trunc/extract, не для сравнения напрямую
Task.objects.filter(
    due_date__month=F('created_date__month') + 1
).update(priority="Critical")

Рекомендуемый подход (Django 5.x)

from django.db.models import F, ExpressionWrapper, IntegerField
from django.db.models.functions import ExtractMonth

# Надёжный вариант через ExtractMonth
Task.objects.annotate(
    due_month=ExtractMonth('due_date'),
    created_month=ExtractMonth('created_date')
).filter(
    due_month=F('created_month') + 1
).update(priority='Critical')
⚠️ Проверить по документации: синтаксис F('field__month') в filter(due_date__month=F('created_date__month')) может вести себя по-разному в разных версиях Django. Для надёжности используйте ExtractMonth.

← К оглавлению урока