【问题标题】:Transforming SQL Query to Django Expression将 SQL 查询转换为 Django 表达式
【发布时间】:2022-01-19 17:07:57
【问题描述】:

假设我有以下 Django 模型和相应的带有一些数据的 SQL 表。我已经简化了模型,使其更清晰。

用户回答:

class UserAnswer(models.Model):
  partquestion = models.ForeignKey(PartQuestion)
  answer = models.CharField()
id answer partquestion_id
1 667 1

部分问题:

class PartQuestion(models.Model):
  question = models.ForeignKey(Question)
  part = models.ForeignKey(Part)
id question_id part_id
1 1 1

解决方案:

class SingleInputSolution(models.Model):
    question = models.ForeignKey(Question)
    content = models.CharField()
id content question_id
1 667 1
2 85 2

我想获得所有用户答案,其中答案等于相应问题的解决方案。我想出了这个 SQL 查询,但真的想不出如何在 Djano 查询中实现它:

select * from (useranswer join partquestion on 
useranswer.partquestion_id = partquestion.id) join solution on 
partquestion.question_id = solution.question_id where answer=content;

这将输出以下内容:

useranswer.id useranswer.answer useranswer.partquestion_id partquestion.id partquestion.question_id partquestion.part_id solution.id solution.content solution.question_id
1 667 1 1 1 1 1 667 1

我只是无法理解 Django 中的这个概念。也许使用 F-Expressions 和一些东西。

感谢您的建议。

【问题讨论】:

  • 你能分享你的模型吗?这将使帮助您变得更加容易。例如,不清楚模型之间是如何相互关联的(通过外键?)。
  • @yagus 哦,当然,对不起。我将模型定义添加到问题中。

标签: python sql django


【解决方案1】:

您可以只使用值和__ 关系来遍历外键。

UserAnswer.objects.values('id', 'answer', 'partquestion_id', 'partquestion_set__id', 'partquestion_set__question_id')

不幸的是,如何获取最后一个表的这些列对我来说还不够明显,但我希望从这个答案中你可以看到如何做到这一点?

【讨论】:

  • 但是“partquestion_set__id”将如何工作?它是一个包含(有时)多个对象的查询集。也许我错过了什么......
  • 在这种情况下是它们之间的反向关系。当你创建一个外键时,django 会创建这个 partquestion_set 属性,它是多对一的关系。
  • 以经典的书籍和作者为例,一个作者可以有很多本书。它们通过从书到作者的 FK 关联。 Django 自动创建 author.book_set 并且你可以获取作者的所有书籍。您可以遍历任意数量的关系。
  • 是的,我也想过这个,但没有让它发挥作用。我终于得到了解决方案。我只需要使用 UserAnswer.objects.filter('solution',...) 而不是访问实际对象集时使用的 'solition_set' 来访问它。感谢您的回答和 cmets 让我走向了正确的方向。我将发布答案。
【解决方案2】:

好吧,我只是在阅读@Swift 的答案和 cmets 后自己弄清楚了。

是:

UserAnswer.objects.filter(partquestion__question__solution__content=F('answer'))

在我得到它之后现在非常简单,但我只是尝试使用 solution_set 而不是 solution

【讨论】:

    【解决方案3】:

    如果你这样定义你的模型:

    class UserAnswer(models.Model):
       question = models.ForeignKey(questions,on_delete=models.CASCADE)
       user_answer = models.CharField()
    
    class questions(models.Model):
       question = models.CharField()
       answer = models.CharField()
    

    那么这个过滤器必须工作

    right_answers = UserAnswer.objects.filter(question__answer = user_answer )
    

    【讨论】:

    • 问题是,实际代码要复杂得多,因此需要使用不同的模型。但是正如我在自己的答案中所写的那样,我已经弄清楚了。不过谢谢:)
    猜你喜欢
    • 1970-01-01
    • 2020-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多