✅ Решения заданий — Урок 22

К оглавлению урока | Задания

⚡ Ответы кратко

  • А-1: b) create()
  • А-2: c) objects
  • А-3: d) save()
  • Б-1: a) first()
  • Б-2: b) exists()
  • Б-3: a-3, b-1, c-4, d-2
  • В-1: b) DoesNotExist
  • Г-1: a) startswith
  • Г-2: d) range
  • Г-3: c) iexact
  • Г-4: a-2, b-4, c-1, d-3
  • Д-1: b) Q

Блок А. Менеджеры и создание записей

Задание А-1 — Ответ: b) create()

create() объединяет создание объекта и вызов save() в одном шаге. Метод save() (вариант a) тоже сохраняет, но требует отдельного создания объекта. Методов add() и insert() в менеджере не существует.

# Правильно — create() за один шаг
book = Book.objects.create(title="1984", author="Orwell",
                           published_date="1949-06-08", price=20)

Задание А-2 — Ответ: c) objects

Стандартный менеджер Django называется objects. Он автоматически добавляется к каждой модели, если вы явно не переопределяете менеджер.

Book.objects.all()   # objects — менеджер по умолчанию

Задание А-3 — Ответ: d) save()

save() используется, когда нужно создать объект, изменить несколько атрибутов и затем сохранить. create() не позволяет изменять объект до сохранения.

book = Book(title="1984", author="Orwell",
            published_date="1949-06-08", price=20)
book.title = "Nineteen Eighty-Four"  # изменяем перед сохранением
book.save()

Блок Б. Чтение записей

Задание Б-1 — Ответ: a) first()

first() возвращает первую запись QuerySet или None. get() требует указать условие и бросает исключение при 0 или >1 результате — это другой сценарий.

Задание Б-2 — Ответ: b) exists()

exists() выполняет оптимизированный SQL-запрос SELECT 1 WHERE ... — быстрее, чем count() > 0 или конвертация QuerySet в список.

# Эффективно
if Book.objects.filter(is_bestseller=True).exists():
    print("Есть бестселлеры")

# Медленнее — не делайте так
if len(Book.objects.filter(is_bestseller=True)) > 0:
    print("Есть бестселлеры")

Задание Б-3 — Ответ: a-3, b-1, c-4, d-2

  • a) values() → 3) Возвращает записи как словари поле-значение
  • b) last() → 1) Возвращает последнюю запись из QuerySet
  • c) all() → 4) Возвращает все записи таблицы как QuerySet
  • d) count() → 2) Возвращает количество записей в QuerySet

Блок В. Метод get()

Задание В-1 — Ответ: b) DoesNotExist

При отсутствии записи — DoesNotExist (или Book.DoesNotExist). При нескольких записях — MultipleObjectsReturned. None возвращают first() и last() — не get().

try:
    book = Book.objects.get(title="Несуществующая")
except Book.DoesNotExist:
    print("Книга не найдена")   # сюда попадём

Блок Г. Lookups и фильтры

Задание Г-1 — Ответ: a) startswith

Правильные Django lookups: __startswith и __istartswith. beginswith, startwith, beginwith не существуют.

Задание Г-2 — Ответ: d) range

__range транслируется в SQL BETWEEN и включает обе границы.

Book.objects.filter(published_date__range=["2020-01-01", "2023-12-31"])

Задание Г-3 — Ответ: c) iexact

Префикс i в Django lookups означает case-insensitive (без учёта регистра). iexact — точное совпадение без учёта регистра.

Задание Г-4 — Ответ: a-2, b-4, c-1, d-3

  • a) icontains → 2) Содержит подстроку без учёта регистра
  • b) in → 4) Значение в заданном списке
  • c) isnull → 1) IS NULL
  • d) contains → 3) Содержит подстроку с учётом регистра

Задание Г-5 — Практика: книги 2010–2020

books = Book.objects.filter(
    published_date__range=["2010-01-01", "2020-12-31"]
)
for book in books:
    print(book.title, book.published_date)

Блок Д. Класс Q

Задание Д-1 — Ответ: b) Q

Класс Q из django.db.models позволяет строить сложные условия с AND (&), OR (|), NOT (~). Остальные варианты — несуществующие классы.

from django.db.models import Q

books = Book.objects.filter(
    Q(is_bestseller=True) | Q(price__lt=15)
)