Опрос отношений ManyToMany в Джанго - PullRequest
1 голос
/ 08 октября 2019

Предположим, у меня есть следующие модели, где у Вопросов и Вариантов есть отношение «многие ко многим», а у Вариантов и Выборщиков - отношение «многие ко многим». (Чтобы понять это лучше, рассмотрите опрос, в котором каждый Вопрос может иметь несколько вариантов, и каждый вариант может быть связан с несколькими Вопросами, и где каждый вариант содержит список людей, проголосовавших за него, и Избиратели могли проголосовать за несколько вариантов.)

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    choices = models.ManyToManyField('Choice')

class Choice(models.Model):
    choice_text = models.CharField(max_length=200)
    voters = models.ManyToManyField('Voter')

    def __str__(self):
        return self.choice_text

class Voter(models.Model):
    name = models.CharField(max_length=500, default='FNU')

    def __str__(self):
        return self.name

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

Поэтому, если Варианты c1 и c2 связаны с Вопросом ques1, а Избиратели v1 и v2 проголосовали за Выбор c1, а Избиратель v3 проголосовал за Выбор c2, затем запустив запрос на вопрос ques1, я бы хотел QuerySet, содержащий [v1, v2, v3].

Есть ли какой-либо запрос для этого?

Высоко неэффективноОбходной путь, конечно, состоит в том, чтобы перебрать ques1.choices и обновлять текущий список всех избирателей с каждой итерацией. Я полагаю, что это можно сделать несколько более эффективным, если использовать select_related, но это не означает наличие чистого запроса.

1 Ответ

0 голосов
/ 08 октября 2019

Мы можем сделать:

Voter.objects.filter(choice__in=ques1.choices.all()).distinct()    # Used distinct() to get unique voters.

Подробнее об этом можно прочитать в Официальной документации Django .

...