Skip to content

Django Web framework. Запросы и их выполнение.

Задача 2. Запросы на аггрегацию и аннотацию.

Необходимо реализовать следующие запросы c применением описанных методов: - Вывод даты выдачи самого старшего водительского удостоверения - Укажите самую позднюю дату владения машиной, имеющую какую-то из существующих моделей в вашей базе - Выведите количество машин для каждого водителя - Подсчитайте количество машин каждой марки - Отсортируйте всех автовладельцев по дате выдачи удостоверения (Примечание: чтобы не выводить несколько раз одни и те же таблицы воспользуйтесь методом .distinct())

Решение

import os
import sys
from django.db.models import Count, Max, Min
import django

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'simple_django_web_project.settings')
django.setup()

from project_first_app.models import CarOwner, DriverLicense, Car, CarOwnership

def execute_queries():
    oldest_license = DriverLicense.objects.aggregate(Min('issue_date'))
    print(f"Самая ранняя дата выдачи удостоверения: {oldest_license['issue_date__min']}")

    latest_ownership = CarOwnership.objects.filter(
        car__model__isnull=False
    ).aggregate(Max('end_date'))
    print(f"Самая поздняя дата владения машиной: {latest_ownership['end_date__max']}")

    car_count_per_driver = CarOwner.objects.annotate(car_count=Count('ownerships__car'))
    print("Количество машин у каждого водителя:")
    for owner in car_count_per_driver:
        print(f"Водитель: {owner.username}, Количество машин: {owner.car_count}")

    car_count_per_brand = Car.objects.values('brand').annotate(count=Count('id'))
    print("Количество машин каждой марки:")
    for car in car_count_per_brand:
        print(f"Марка: {car['brand']}, Количество: {car['count']}")

    sorted_owners = DriverLicense.objects.select_related('owner').order_by('issue_date').distinct()
    print("Водители, отсортированные по дате выдачи удостоверения:")
    for license in sorted_owners:
        print(f"Водитель: {license.owner.username}, Дата выдачи: {license.issue_date}")

if __name__ == "__main__":
    execute_queries()

Описание запросов

Задача 1. Дата выдачи самого старшего водительского удостоверения

Используется метод aggregate с функцией Min, чтобы найти минимальную дату в поле issue_date модели DriverLicense:

oldest_license = DriverLicense.objects.aggregate(Min('issue_date'))

Задача 2. Самая поздняя дата владения машиной

Фильтруем записи CarOwnership, у которых есть модель автомобиля (model__isnull=False), и используем aggregate с Max для получения самой поздней даты окончания владения:

latest_ownership = CarOwnership.objects.filter(car__model__isnull=False).aggregate(Max('end_date'))

Задача 3. Количество машин для каждого водителя

Используется annotate и Count для подсчёта связанных машин для каждого водителя через поле ownerships:

car_count_per_driver = CarOwner.objects.annotate(car_count=Count('ownerships__car'))

Задача 4. Количество машин каждой марки

Используется метод values для группировки по brand и подсчёта количества машин через annotate:

car_count_per_brand = Car.objects.values('brand').annotate(count=Count('id'))

Задача 5. Сортировка автовладельцев по дате выдачи удостоверения

Используется метод select_related для объединения с моделью CarOwner и order_by для сортировки:

sorted_owners = DriverLicense.objects.select_related('owner').order_by('issue_date').distinct()

Вывод в консоли:

Вот вывод результата