Django generic DetailView: как лучше всего опционально включить объект, связанный с реверсом?

Фон

Модели

Допустим, у меня есть django generic DetailView, который я использую для отображения одного экземпляра модели под названием Car. Затем допустим, что у меня есть другая модель под названием Race. Среди многих полей эта модель Race имеет поле ForeignKey, которое связано с Car (т. е. Car, которое Driver (пользователь) использовал для Race).

Пример models.py

from django.conf import settings

class Car(models.Model):
    """ a bunch of fields, including many fk fields """

class Race(models.Model):
    car = models.ForeignKey(Car, on_delete=models.CASCADE, related_name="races")
    driver = models.models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    """ a bunch of other fields, including fk fields """

View

Допустим, у меня есть общий DetailView, который пользователи моего сайта уже давно используют для просмотра одного автомобильного объекта.

Пример views.py

Это очень упрощенный queryset (мой реальный набор запросов имеет такую же структуру, но больше полей, связанных с обратными связями, с соответствующими связанными полями).

from django.views import generic

class CarDetailView(generic.DetailView):
    model = Car
    queryset = Car.objects.select_related(
        """ a bunch of related fields """
    ).prefetch_related(
        """ some reverse related fields """,
            Prefetch(""" a reverse related field """, SomeReverseRelatedField.objects.select_related(""" some of its related fields """)),
    )

Новая функция :)

Однако недавно я реализовал способ, с помощью которого мои пользователи могут "управлять" автомобилем в гонке прямо из этого DetailView. У меня есть API django ninja, включенный в мое приложение Django, и я использую vanilla js, чтобы мои пользователи могли создавать объект Race, а затем выполнять последующие действия, создающие дополнительные, вложенные объекты, которые являются другими полями с внешними ключами для Race, которые они только что создали. Это своего рода мини-приложение внутри моего общего веб-приложения django.

До появления этой новой функции мой шаблон для этого вида был чрезвычайно плотным и сложным. С этой новой функцией он стал еще более плотным и сложным.

Проблема

У меня все отлично работает, но мне нужен способ, чтобы пользователи могли получить доступ к Race и связанному с ним Car объекту позже способом, который почти идентичен текущему Car DetailView.

Итак, все сводится к необязательному Race объекту, который я хотел бы прикрепить к моему Car DetailView.

Я не хочу создавать копию своего шаблона, которая просто начинается на одном уровне с Car (т.е. делать DetailView для Race и рефакторить мой существующий шаблон для Car, чтобы получить доступ к объекту Car (и всем его многочисленным связанным объектам) через его обратную связь Race). Я хотел бы сохранить мой текущий шаблон и просто использовать условные теги шаблона Django и условные блоки javascript для добавления деталей Race в случае наличия переменной сессии, указывающей на Race.

Потенциальное решение

Рабочий процесс будет выглядеть следующим образом:

  • Пользователь нажимает на ссылку, связанную с объектом Race
  • Простой вид перенаправления будет
    • создаст переменную сессии с Race объектом pk
    • перенаправить пользователя на Car DetailView
  • Car DetailView, если есть "гоночная" переменная сессии, создаст контекстную переменную для Race объекта (я бы обработал это в get_context_data() методе представления)
  • Шаблон будет включать данные из объекта Race по мере необходимости (вместе со скрытым элементом ввода или чем-то, что запускает условный блок javascript).

Вопрос

  • Не будет ли вышеописанное слишком запутанным способом решения этой проблемы? Есть ли более простой способ, который позволит избежать дублирования моего шаблона (что приведет к головной боли при обслуживании дублирования в будущем)?
  • Как я буду работать с кверисетом с необязательным объектом, связанным с реверсом?
    • (мне не нужны все связанные с реверсом Race объекты; мне нужен только один). Я бы поместил такую строку в ветвь метода get_context_data(), которая будет запущена при наличии сессионной переменной "race_id": context['race'] = Race.objects.filter(pk=self.request.session['race_pk']) но как мне эффективно запросить ее?
Вернуться на верх