【问题标题】:How can I join multiple tables in Django 1.9?如何在 Django 1.9 中加入多个表?
【发布时间】:2016-08-22 10:17:48
【问题描述】:


我需要帮助。我的问题是我试图在 Django 1.9 中加入多个表/模型((Question, Answer, User)),以获得由某个用户提出的一组问题的答案。

我已经有了我想要的 sql 查询:

 SELECT q.id, q.title, COUNT(a.id) AS total_answers 
 FROM review_question AS q
 JOIN review_answer AS a ON q.id = a.question_id
 JOIN users_user AS u ON q.user_id = u.id
 WHERE q.user_id = 1
 GROUP BY q.id, q.title;

这是我的模型:

review/models.py

[问题]

class Question(models.Model):
    user = models.ForeignKey(User, db_index=True, null=True, blank=True)
    tag = models.ManyToManyField(Tag)
    title = models.CharField(max_length=200)

[回答]

class Answer(models.Model):
    question = models.ForeignKey(Question)
    user = models.ForeignKey(User, db_index=True, null=True, blank=True)

users/models.py

[用户]

class User(models.Model):
    username = models.CharField(max_length=100, unique=True)

顺便说一句,在我的文件 users/views.py 我有下一个:

class UserDetailView(DetailView):
    model = User

    def get_context_data(self, **kwargs):
        # calling the get_context_data parent here
        questions = Question.objects.filter(user = context['object']).order_by('created')

但是,我只得到用户提出的所有问题

我一直在尝试寻找如何将上面的查询转换为 django-orm 的方法,但是我仍然无法做到这一点。任何帮助将不胜感激。

【问题讨论】:

  • 你已经成功了。现在您有问题Answer.objects.filter(question__in=questions)。检查这个:docs.djangoproject.com/es/1.9/ref/models/querysets/#in
  • Answer.objects.filter(question__user=user) 怎么样?编辑:我没有注意到您查询中的 GROUP BY,我的建议不会这样做。
  • @MikeVelazco 谢谢,我会检查一下,看看我能做什么;)
  • @PauloAlmeida 没错。如果我需要知道某个用户有多少答案,您的建议会起作用,但我需要的是每个问题有多少答案。无论如何,谢谢。
  • 你研究过聚合吗? stackoverflow.com/questions/629551/…

标签: python django django-orm


【解决方案1】:

终于可以解决我的问题了。

我做的是下一个:

在我的文件 users/views.py

class UserDetailView(DetailView):
    model = User

    def get_context_data(self, **kwargs):
        # Calling the get_context_data parent
        questions = Question.objects.filter(user = context['object']).order_by('created')

        tags = [ question.tag.all() for question in questions ]

        total_answers = self.get_total(questions) # Calling the function that return the total answer by question of a specific user
        context['question_tags'] = zip(questions, tags, total_answers) #Zipping the lists with results to use it in the template

        return context

    def get_total(self, questions):
        #Return the total answers that a question has (Here is the trick!)
        return [
            Answer.objects.filter(question__id=question.id).annotate(num_answers=Count('question')).count() for question in questions]

这就是我所做的一切。 最后,我要特别感谢@PauloAlmeida 和@MikeVelazco 的帮助!

【讨论】:

  • 如果你打算使用列表推导,你可能只需要return [question.answer_set.count() for question in questions]
  • 是的,你是对的。现在看起来好多了;)但是,你能解释一下.answer_set.count()吗?我不太明白。
  • 没关系,我已经在文档中找到了。看起来这是一种更好的方法。再次感谢您。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-05
  • 2017-06-03
  • 2020-01-21
  • 1970-01-01
  • 2021-09-11
  • 1970-01-01
  • 2016-07-27
相关资源
最近更新 更多