Django ORM извлекает данные по 2 уровням отношения внешнего ключа - PullRequest
0 голосов
/ 22 марта 2019

У меня есть следующие модели:

class Project(models.Model):
     name = models.CharField(max_length=300, unique=True)
     description = models.CharField(max_length=2000)

class TemporaryUser(models.Model):
    username = models.CharField(max_length=400)
    project = models.ForeignKey(
        Project,
        on_delete=models.CASCADE,
        related_name='users'
    )

class QuestionSession(models.Model):
    project = models.ForeignKey(
        Project,
        on_delete=models.CASCADE,
        related_name='sessions',
        blank=True,
        null=True,
        default=None
    )

class Question(models.Model):
    # stores the main json object with all required information
    description = JSONField(
        max_length=10000, blank=True, null=True, default=None
    )

    question_session = models.ForeignKey(
        QuestionSession,
        on_delete=models.CASCADE,
        related_name='questions',
        blank=True,
        null=True,
        default=None
    )

class Answer(models.Model):
    question = models.ForeignKey(
        Question,
        related_name='answers_list',
        on_delete=models.CASCADE)

    answer = models.CharField(max_length=500)
    answered_by = models.ForeignKey(
        TemporaryUser,
        on_delete=models.CASCADE,
        related_name='answers',
        blank=True,
        null=True,
        default=None
    )

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

Я могу выбрать всех пользователей и все ответы в конкретном проекте со следующими данными:

TemporaryUser.objects.all().filter(project__id=project_id)

Как я могу сделать то же самое в течение сеанса?Я действительно не знаю, как это сделать, мне нужно фильтровать пользователей по сеансам, есть ли способ, как это сделать с моими отношениями?

Ответы [ 3 ]

2 голосов
/ 22 марта 2019

Вы имеете в виду как:

TemporaryUser.objects.filter(project__sessions__id=id)
0 голосов
/ 22 марта 2019

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

users = TemporaryUser.objects.filter(project__sessions=id)

Однако, если вы хотите получить больше данных, относящихся к этому сеансу, возможно, вам следует подумать о том, чтобы извлечь из самого сеанса (см. Следующие отношения в обратном направлении ). Будьте осторожны, так как количество запросов к базе данных не оптимизировано.

session = Session.objects.get(pk=id)
users = session.project.users.all()
questions = session.questions.all()

Вы можете использовать select_related и prefetch_related , если вы хотите делать меньше запросов. Это может быть очень важно, если вы заинтересованы в получении данных для списка сеансов, а не только для одного.

0 голосов
/ 22 марта 2019

Я думаю, что его чище использовать обратное отношение здесь:

session = QuestionSession.objects.first()
session.project.users.all()
# as User model has a FK with Project , and it has related_name="users"

Вы также можете использовать это в своем шаблоне:

{% for qs in questionsessions %}  // questionsessions is the queryset of QuestionSession
     {% for user in qs.project.users.all %}
            {{ user.username }}
     {% endfor %}
{% endfor %}
...