Запрос данных, связанных через внешний ключ

У меня есть 2 модели, связанные между собой "Проект" и "Событие". Event имеет FK к Project

Я хочу вернуть все события, которые относятся только к проекту.

У меня есть базовое представление, которое возвращает конкретный проект, и я пытаюсь включить список событий в это представление.

def show_project_details(request,project_id):
    today = now().date()
    project = Project.objects.get(pk=project_id)
    events = Event.objects.event_list = Event.objects.filter(event_date__gte=today).order_by('event_date')
    events_list = Event.objects.get(project_name_id=project_id)
    form = ProjectForm(request.POST or None, instance=project)

    return render(request, 'pages/project_details.html', {"project": project, "form": form, "events": events, 'events_list':events_list})

но возвращается

Event matching query does not exist.

Есть идеи?

для получения всех событий, связанных с определенным проектом использовать

project = Project.objects.get(pk=project_id)
events = project.event_set.filter(event_date__gte=today).order_by('event_date')

так что полный вид уменьшится до

def show_project_details(request,project_id):
    today = now().date()
    project = Project.objects.get(pk=project_id)
    events = project.event_set.filter(event_date__gte=today).order_by('event_date')
    form = ProjectForm(request.POST or None, instance=project)

    return render(request, 'pages/project_details.html', {"project": project, "form": form, "events": events})

Ответ Брайана Обота - очень хорошее решение вашей актуальной проблемы.


Чтобы ответить на ваш вопрос, почему вы получаете эту специфическую ошибку с вашим кодом:

Событие, соответствующее запросу, не существует.

Поскольку вы не предоставили (пока) свои модели, я могу только предположить, что ошибка возникает для этой строки кода:

events_list = Event.objects.get(project_name_id=project_id)

objects.get всегда будет выдавать ошибку, если не найдет в точности 1 объект. Для получения данных, которые могут возвращать от 0 до многих результатов (как в случае с обычными обратными отношениями внешнего ключа), следует использовать filter.

Ваш текущий код должен работать, если вы измените приведенную выше строку на:

events_list = Event.objects.filter(project_name_id=project_id)

Это действительно вернет список (фактически queryset) - который также может быть пустым.


С точки зрения производительности / количества выполняемых операций над базой данных:

Оба способа (project.event_set и Event.objects.filter) приведут к появлению дополнительных запросов к базе данных.

Если вы хотите избежать этого и получать все данные при получении данных проекта, вам придется работать с аннотациями.

Пока вы не испытываете никаких проблем, можно оставить все как есть. Если вам интересно заглянуть в эту область, читайте дальше: https://docs.djangoproject.com/en/3.2/ref/models/querysets/#annotate

Вернуться на верх