Как бы я сделал это без явного SQL JOIN? - PullRequest
0 голосов
/ 15 апреля 2009

У меня есть модель с именем Question, а другая - с именем Answer.

class Question(models.Model):
    text = models.CharField(max_length=140)

class Answer(models.Model): 
    user = models.ForeignKey(User)
    question = models.ForeignKey(Question)
    uncertain = models.BooleanField()
    text = models.CharField(max_length=30)

Теперь я хотел бы иметь QuerySet questions, который эквивалентен Question.objects.all(), но , включая ответы текущего пользователя . Я почти полностью уверен, что это может быть достигнуто явным JOIN в SQL, но я уверен, что есть лучший способ сделать это, используя ORM Джанго.

Так как бы я это сделал?

РЕДАКТИРОВАТЬ: Чтобы уточнить, я хотел бы иметь возможность перебрать QuerySet, например, for q in questions и затем сможет увидеть, ответил ли пользователь на него через что-то вроде q.answered, которое может быть логическим, или q.answer, которое может быть самим объектом ответа (или None).

Ответы [ 3 ]

1 голос
/ 15 апреля 2009

Я думаю, ты слишком много думаешь. По сути, вы хотите знать (насколько я могу судить - поправьте меня, если я ошибаюсь), на какие вопросы ответил пользователь, а на какие нет (дополнение). Итак:

user_answered_questions = set([answer.question for answer in user.answer_set.all()])

Тогда оставшиеся без ответа вопросы - это все остальное. Итак:

user_unanswered_questions = set(Question.objects.all()) - answered_questions

Смысл делать это таким образом, а не решением Узи, состоит в том, что вы должны использовать то, что знаете раньше, а не позже. Если вы фильтруете answer_set для каждого вопроса по пользователю, ваш начальный запрос будет выбирать каждый отдельный ответ и каждый вопрос в этих таблицах. Исходя из известных данных (то есть пользователя), мы выбираем только ответы и вопросы, связанные с этим пользователем.

EDIT:

Итак, если вы хотите объединить два набора в один список, существует множество способов, например, сделать это, создав список кортежей:

questions = [(q, q in user_answered_questions) for q in Question.objects.all()]

Затем вы можете перебирать вопросы, сохраняя порядок набора запросов:

for q in questions:
    print "it is %s that this user answered the \"%s\" question" % (q[1], q[0])

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

1 голос
/ 15 апреля 2009

Вы ищете что-то подобное?

[ item.question for question in Answer.objects.filter(user=request.user) ]

Или, может быть, вы хотите сделать

questions = Question.objects.all()
for question in questions:
    question.answer = question.answer_set.filter(user=request.user)

Полагаю, я не понимаю вопроса и в каком направлении вы хотите идти ...

РЕДАКТИРОВАТЬ: Хорошо, на основе вашего редактирования, возможно, последнего ... вы можете увидеть, является ли это пустой список или галочка на .count () и посмотреть, если значение больше 0.

0 голосов
/ 15 апреля 2009

Что не так с

Question.objects.filter(answer__user=current_user).select_related()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...