我尝试获取与主题question
In [17]: topic = Topic.objects.filter(text__icontains='question')
发出以下命令时会抛出错误:
In [15]: questions =
Topic.objects.filter(text__icontains='question').entry_set.all()
AttributeError: 'QuerySet' object has no attribute 'entry_set'
因此,应首先检索id:
In [18]: [ i.id for i in topic]
Out[18]: [14]
In [19]: Topic.objects.get(pk=14).entry_set.all()
Out[19]:
<QuerySet [<Entry: Why encapsulate button
最后,得到我的结果。
然而,它是如此笨重,如何优雅地完成它?
class Topic(models.Model):
"""A topic the user is learning about."""
text = models.CharField(max_length=200)
date_added = models.DateTimeField(auto_now_add=True)
owner = models.ForeignKey(User)
def __str__(self):
"""Return a string representation of the model."""
return self.text
class Entry(models.Model):
"""Something specific learned about a topic"""
topic = models.ForeignKey(Topic)
title = models.CharField(max_length=200)
text = models.TextField()
tags = models.CharField(max_length=200)
date_added = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name_plural = 'entries'
def __str__(self):
"""Return string representation of the model"""
return self.text[:50] + "..."
答案 0 :(得分:3)
您可以通过topic
参考:
Entry.objects.filter(topic__text__icontains='question')
这是一个查询集,其中包含所有 Entry
个实例,其中topic
指的是Topic
个实例text
属性包含 - 当我们忽略大小写时 - &#39;问题&#39;`substring。
因此,我们使用topic__
来过滤属于相应主题的属性。例如,我们还可以使用以下方法过滤主题的主键:
Entry.objects.filter(topic__pk=14)
双下划线(__
)因此有点类似于Python中我们通常使用点(.
)来访问属性:通过双下划线链我们可以获得属性可以通过外键获得,因此可以对其执行过滤,聚合等。
使用这种手动过滤方式的另一个优点是首先获取pk
的{{1}} s列表,这个过滤是在单个查询中编码的(对于大多数数据库系统来说,当然不能保证在每个可能的数据库系统中都可以实现这一点,但像MySQL这样的流行系统肯定支持这一点。虽然查询本身比获取主题的主键更昂贵。我们在这里立即获得Topic
个实例,而自己做这些查询通常会导致更多查询,从而导致解决方案效率降低。