Django查询按字段对选择不同的内容

8

我有一个名为“submission”的字段,其中包含用户和问题。如何获取SQL搜索结果,仅给出每个用户-问题对的一个结果列表?

模型如下:

class Problem(models.Model):
    title = models.CharField('Title', max_length = 100)
    question = models.TextField('Question')

class Submission(models.Model):
    user = models.ForeignKey(User)
    problem = models.ForeignKey(Problem)
    solution = models.CharKey()
    time = models.DateTimeField('Time', auto_now_add=True)

你指的"field which has a user and a problem"是什么意思?你是在谈论Django模型吗?请发布相关代码。 - Manoj Govindan
这是模型的样子: 问题:标题,问题描述 提交:问题(外键),用户(外键),内容 用户:认证用户假设有两个问题p1和p2, 以及两个用户u1和u2。其中u1对于p1有两次提交s1和s2, 对于p2有一次提交s3; u2对于p1有一次提交s4, 对于p2有两次提交s5和s6。因此我想要一个查询集结果,如下所示:s2、s3、s4、s6即忽略具有相同用户和问题的旧记录 s2、s3. - crodjer
2个回答

20

试试这个:

distinct_users_problems = Submission.objects.all().values("user", "problem").distinct()
它会给你一个像这样的字典列表:
[{'problem': 1, 'user': 1}, {'problem': 2, 'user': 1}, {'problem': 3, 'user': 1}]

包含所有不同的对。

实际上会得到您通常的SELECT DISTINCT SQL查询。


3
更新2:
(阅读原帖作者的评论后)我建议添加一个新模型来追踪最新提交。将其命名为“LatestSubmission”。
class LatestSubmission(models.Model):
    user = models.ForeignKey(User)     
    problem = models.ForeignKey(Problem)
    submission = models.ForeignKey(Submission)

然后,您可以选择:
  1. 重写 Submission.save() 函数,在用户发布新问题的解决方案时创建/更新 LatestSubmission 中的条目
  2. 将执行相同操作的函数附加到适当的 信号 上。
这样,LatestSubmission 将包含每个问题-用户-提交组合的一行,指向每个用户对该问题的最新提交。一旦您完成了这个步骤,就可以触发单个查询:
LatestSubmission.objects.all().order_by('problem')

更新:
由于原帖已经发布了示例代码,现在可以将解决方案更改如下:
for user in User.objects.all(): # Get all users
    user.submission_set.latest('time') # Pick the latest submission based on time.

在没有任何基于日期/时间的标准来决定哪个是“旧的”或“新的”的情况下,您可以使用Submission的主键(id)来“忽略旧的条目”。
for user in User.objects.all(): # Get all users
    user.submission_set.latest('id') # Pick the latest submission by each user.

我已经将模型细节添加到我的问题中。 这将为我提供用户最后提交的查询集,而我想要的是所有问题的最新结果。我想在提交字段上运行SQL命令,并按提交时间排序获取提交列表,如果同一用户在一个问题中有多个提交,则只包括一个结果。 - crodjer
@Rohan Jain:考虑到你目前的模型结构,我不确定你是否可以使用一个SQL查询来完成。我想知道这里是否有其他人能够提供一个合适的答案。 - Manoj Govindan
我现在正在通过为提交添加一个is_latest布尔字段来完成这个任务.....谢谢你的帮助 :) - crodjer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接