按django的限制1组 [英] Group by limit 1 in django

查看:91
本文介绍了按django的限制1组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Django中有以下模型(简化为简洁):

I have the following models in Django (simplified for brevity):

class DistinctWord(models.Model):
    ...

class Word(models.Model):
    distinct_word = models.ForeignKey('DistinctWord', related_name='words')
    ...

class UserWord(models.Model):
    distinct_word = models.ForeignKey(DistinctWord, related_name='user_words')
    ...

在单词中:DistinctWord是从彼此派生的单词的根(例如,愚蠢,sillier,silliest),UserWord是用户的字典。所以,当一个用户向他的字典添加一个Word时,他实际上添加了根词(和所有相关的单词)。所以,当他请求查看/研究他的字典中的单词时,我必须带一个实际的词(例如第一个)。

In words: DistinctWord is the root of words derived from each other (e.g., silly, sillier, silliest), and UserWord is the user's dictionary. So, when a user adds a Word to the his dictionary he actually adds the root word (and thus all related words). So, I must bring an actual Word (e.g., the first one) when he requests to see/study the words in his dictionary.

也就是说,对于给定的UserWords的查询(例如 uw ),我想检索第一个Word与该查询集中的每一行相关(最好是在数据库中进行一次或几次访问,而不是每一行)。这将是一个简单的连接,分组和限制1在原始sql,但我不能把我的头围绕在Django。

That is, for a given queryset of UserWords (say uw), I would like to retrieve the first Word related for each row in that queryset (preferably in one or a few trips to the database, not one for each row). This would be a simple join, group by and limit 1 in raw sql, but I could not wrap my head around it in Django.

推荐答案

让我们:

uw # be a given queryset of UserWord's
dw # be a queryset of DistinctWords (will be derived from `uw`)
w  # be a queryset of Words needed (will be derived from `dw`)

每个 UserWord 有一个 DistinctWord ,每个 DistinctWord 有许多 Word (松散地表示为code> uw> dw< w )

Each UserWord has a DistinctWord, and each DistinctWord has many Word's (loosely denoted as uw>dw<w).

这是我的答案:

dw_id=uw.values_list('distinct_word_id', flat=True) # 1: get dw ids from uw
dw=DistinctWord.objects.filter(id__in=dw_id)        # 2: get dw's
w_first_id=dw.annotate(first_word=Min('words')).values_list('first_word', flat=True) 
                                                    # 3: find id of first word 
w=Word.objects.filter(id__in=w_first_id)            # 4: get first words

总结:林es 1和2得到 dw ,应该只是一次到数据库

In summary: lines 1 and 2 get dw and should be just 1 trip to the database

第3行使用注释,后跟 values_list 找到第一个相关的 Word

line 3 uses annotate followed by values_list to find the id of first related Word

第4行带来了上一步中生成的id的实际Word对象。第3行和第4行应该是另一次访问数据库,因为 annotate 不是终端语句。

Line 4 brings the actual Word objects from the id's generated in the previous step. Lines 3 and 4 should be another trip to the database since annotate is not a terminal statement.

因此,2次访问数据库(未测试)。

Thus 2 trips to the database (not tested).

这篇关于按django的限制1组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆