【问题标题】:In Django, how do I get all the instances of a model that have other instances of a related model attached to it with a ForeignKey field?在 Django 中,如何获取一个模型的所有实例,该模型的其他实例通过 ForeignKey 字段附加到它上面?
【发布时间】:2017-08-28 10:51:15
【问题描述】:

我正在尝试编写一个查询来检索至少附加了一个post 的所有类别。换句话说,我想“排除”任何没有帖子的类别。

这些是我为CategoryPost 设计的模型:

class Category(models.Model):
    title = models.CharField(max_length=250)
    slug = models.SlugField(max_length=250, unique=True)


class Post(models.Model):
    title = models.CharField(max_length=250)
    slug = models.SlugField(max_length=250, unique=True)
    body = models.TextField()
    category = models.ForeignKey(Category, blank=True, default="")

这是我在查询中使用的代码,目前它会获取所有类别,即使没有“附加”帖子:

categories = Category.objects.all()

我想要的是这样的:

categories = Category.objects.filter(
    #  Only ones that have at least one Post that has it's 'category' field set to it.
)

我搜索了文档和其他任何地方,但找不到解决方案。

请告诉我如何做到这一点。

【问题讨论】:

  • Post 模型有一个指向Topic 模型的外键,而您称它为categories。我不确定我是否理解这种关系如何与Category 模型一起使用。
  • @AKS 很抱歉造成混乱。我在问题中用 Category 替换了 Topic,认为这样可以更清楚地说明我想要实现的目标。我现在已经解决了,谢谢。
  • 请检查答案。

标签: python sql django orm


【解决方案1】:

您可以使用以下查询:

categories = Category.objects.filter(post__isnull=False).distinct()

这将获得post 不为空的所有类别。由于一个类别可能有多个帖子,因此您将获得具有相同 ID 的重复实例。使用distinct 删除重复的类别。

注意,distinct(*fields) 是 postgresql 特有的。如果您使用不同的数据库,只需使用distinct()

【讨论】:

  • 该代码出现以下错误:NotImplementedError at / DISTINCT ON fields is not supported by this database backend.最后删除 .distence('id') 消除了错误,但正如你提到的那样,它得到了重复的实例。
  • 我明白了。将 distinct 与字段一起使用纯粹是 postgresql 特定的,而且您似乎使用的是不同的数据库。您可以使用distinct(),无需任何字段。
  • 我正在使用 SqlLite。使用 distinct() 解决了这个问题。非常感谢!
【解决方案2】:

通过查询Post 获取不同类别的所有唯一类别ID,然后按ID 过滤类别。

id_list = Post.objects.values_list('category_id').distinct()
catgories = Category.objects.filter(id__in=id_list)

【讨论】:

    猜你喜欢
    • 2014-07-19
    • 2014-05-24
    • 2017-05-02
    • 2020-12-05
    • 2018-07-30
    • 2011-04-19
    • 2019-01-25
    • 1970-01-01
    • 2018-01-15
    相关资源
    最近更新 更多