如何根据递归ManyToManyField的值创建Django查询集?

问题描述 投票:0回答:1

我有一个字典应用程序,其中单词(引理)可以选择由其他单词组成。在我的

models.py
中,这看起来像:

class Lemma(models.Model):
    cf = models.CharField(max_length=200) #citation form
    pos = models.ForeignKey(Pos, on_delete=models.CASCADE) #part of speech
    components = models.ManyToManyField("self", symmetrical=False, blank=True) #component Lemma

我想返回两个查询集:

  1. 所有复合动词:在 self.components 中具有值且 self.pos.term="verb" 的引理
  2. 复合动词的所有独特组成部分都是名词:引理是其他一些引理的 self.component_set() 的值,并且它们本身具有 self.pos.term="noun"。

我想使用视图将这两个列表传递给模板。

我能够很容易地获得查询集 1,但是我对查询集 2 的解决方案都非常复杂。我的

views.py
中的相关课程如下所示:

class CompVerb(generic.ListView):
    model = Lemma
    queryset = Lemma.objects.filter(
        Q(pos__term="verb") & ~Q(components=None)
    ).order_by("cf") #queryset 1, compound verbs

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        nouns = self.queryset.values_list("components")
        nouns = set([Lemma.objects.get(pk=l[0]) for l in nouns])
        nouns= [l for l in nouns if l.pos.term == "noun"]
        context["nouns"] = nouns #queryset 2, nouns that are components of compound verbs

        return context 

这也为我的

verbs
变量留下了一个常规列表,而不是一个正确的查询集,我可以在其中使用
.order_by()
方法按引文形式对这个字母顺序列表进行排序。

是否有更好的方法可以返回查询集对象?

django django-views
1个回答
0
投票

可以反向查询:

class CompVerb(generic.ListView):
    model = Lemma
    queryset = Lemma.objects.filter(
        ~Q(components=None), pos__term='verb'
    ).order_by(
        'cf'
    )  # queryset 1, compound verbs

    def get_context_data(self, **kwargs):
        return super().get_context_data(
            **kwargs,
            nouns=Lemma.objects.filter(lemma__in=self.queryset, pos__term='noun')
        )

您的

queryset
将会重复
Lemma
很多次,因为有相关的
components
,因此您可能需要使用
.distinct()
 [Django-doc]
来防止这种情况.

© www.soinside.com 2019 - 2024. All rights reserved.