2009-04-15 54 views
0

我有一个叫做Question的模型,另一个叫做Answer。现在如何在没有显式SQL JOIN的情况下执行此操作?

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()包括当前登录的用户的回答。我几乎完全确信,这可以通过SQL中的显式JOIN来完成,但我确定有更好的方法来使用Django的ORM来完成此操作。

那么我该怎么做呢?

编辑:为了澄清,我希望能够循环查询集,例如, for q in questions然后能够看到用户是否通过可能是布尔值的q.answered或可能是Answer对象本身(或None)的q.answer之类的东西来回答它。

回答

1

你在找这样的事吗?

[ 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

后者是一个我可能寻找。我很好奇,虽然......第一个显然会碰到数据库一次,但后者会碰到数据库多少次? – 2009-04-15 09:11:02

+0

是的,后者似乎工作,完美!但是,问题依然存在。它会不止一次地触及数据库? – 2009-04-15 09:15:21

+0

一次用于初始查询,每个问题加一次。我想知道......在即将发布的1.1版本中使用聚合可能会有更高效的方式......我不得不考虑它。 – uzi 2009-04-15 09:16:12

1

我认为你是在推翻事物。基本上你想知道的是什么(据我所知 - 如果我错了,纠正我)某个用户回答了哪些问题,哪些问题没有(补充)。所以:

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

然后没有答案的问题就是一切。所以:

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

这样做而不是uzi的解决方案是,你应该使用你知道得早点而不是晚点。如果您按用户筛选每个问题的answer_set,则您的初始查询将选择这些表中的每个答案和每个问题。从已知数据(即用户)开始,我们只选择与该用户有关的答案和问题。

编辑:

所以,如果你再要两套组合成一个单独的列表,还有一堆的方式,你可以例如这样做是通过创建元组的列表:

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]) 

它不漂亮,但你明白了吧 - 你已经确定你想要什么,以确定,这只是一个扭曲它到你碰巧需要的任何数据结构的问题。

0

有什么不对

Question.objects.filter(answer__user=current_user).select_related() 
相关问题