【问题标题】:Django query select distinct by field pairsDjango查询选择不同的字段对
【发布时间】:2011-03-29 20:07:54
【问题描述】:

我的“提交”字段有一个用户和一个问题。我怎样才能得到一个 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)

【问题讨论】:

  • “有用户和问题的字段”是什么意思?你在谈论 Django 模型吗?贴出相关代码。
  • 模型是这样的: Problem: title, question Submission: problem(foreignkey), user(foreignkey), content User: auth user 假设p1, p2有两个问题,u1, u2是两个用户u1有两个提交s1,s2用于p1,一个(s3)用于p2,u2有一个用于p1(s4),两个用于p2(s5,s6)所以我想要一个这样的查询集结果:s2,s3,s4,s6即忽略具有相同用户问题 s2、s3、 的旧问题

标签: python django django-queryset


【解决方案1】:

更新 2

(在阅读了 OP 的 cmets 之后)我建议添加一个新模型来跟踪最新提交。叫它LatestSubmission

class LatestSubmission(models.Model):
    user = models.ForeignKey(User)     
    problem = models.ForeignKey(Problem)
    submission = models.ForeignKey(Submission)

然后你可以

  1. 覆盖 Submission.save() 以在用户每次发布问题的新解决方案时创建/更新 LatestSubmission 中的条目
  2. 将执行相同操作的函数附加到合适的signal

这样LatestSubmission 将在每个问题-用户-提交组合中包含一行,指向每个用户最近提交的问题。一旦你有了这个,你就可以触发一个查询:

LatestSubmission.objects.all().order_by('problem')

更新

由于OP已经发布了示例代码,现在可以将解决方案更改如下:

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 命令并获取按提交时间排序的提交列表,如果同一用户在一个问题中有多个提交,则仅包含一个结果。
  • @Rohan Jain:我不确定您是否可以在给定您的 current 模型结构的情况下使用 one SQL 查询来做到这一点。我想知道这里的其他人是否可以提出合适的答案。
  • 我现在通过为提交添加一个 is_latest 布尔字段来执行此操作.....thanx fr ur help :)
【解决方案2】:

试试这个:

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 查询。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-14
    • 1970-01-01
    • 2018-06-02
    • 1970-01-01
    • 2013-10-23
    • 2018-11-07
    • 2013-04-25
    • 2011-10-26
    相关资源
    最近更新 更多