相关对象的 Django 查询集,在对原始模型进行预过滤之后

标签 django django-models

给定一个模型的查询集,我想获取与外键相关的另一个模型的查询集。以 Django 项目文档的博客架构为例:

class Blog(models.Model):
    name = models.CharField(max_length=100)
    tagline = models.TextField()

    def __unicode__(self):
        return self.name

class Author(models.Model):
    name = models.CharField(max_length=50)
    email = models.EmailField()

    def __unicode__(self):
        return self.name

class Entry(models.Model):
    blog = models.ForeignKey(Blog)
    headline = models.CharField(max_length=255)
    body_text = models.TextField()
    pub_date = models.DateField()
    mod_date = models.DateField()
    authors = models.ManyToManyField(Author)
    n_comments = models.IntegerField()
    n_pingbacks = models.IntegerField()
    rating = models.IntegerField()

    def __unicode__(self):
        return self.headline

假设我有一个 author对象,我想把作者写过的每个博客作为查询集。我做类似 author_blogs = [entry.blog for entry in author.entry_set] 的事情.但是在这种情况下我留下了一个列表,而不是一个查询集。有没有一种方法可以直接使用 ORM 查询来执行此操作,因此我可以使用 use_for_related_fields = True 通过自定义条目管理器进行设置并执行类似 author_blogs = author.entry_set.blogs 的操作,并获得查询集的延迟评估等好处?

编辑场景和解决方案

因此,我在事后意识到我的问题的应用与我在上面提出的方式略有不同,对此丹尼尔罗斯曼的情况很有意义。我的情况真的更像author.entry_set.manager_method().blogs ,其中 manager_method()返回 Entry 对象的查询集。我接受了他的回答,因为它启发了我找到的解决方案:
author_blogs = Blog.objects.filter(entry__in=author.entry_set.manager_method())

好消息是它只使用一个数据库查询。这有点棘手和冗长,所以我认为最好定义 blogs()作为 Author 的对象方法,返回上述内容。

最佳答案

这个技巧是记住,如果你想要一个博客查询集,你应该从博客模型开始。然后,您可以使用双下划线语法来遵循关系。所以:

author_blogs = Blog.objects.filter(entry__authors=author)

关于相关对象的 Django 查询集,在对原始模型进行预过滤之后,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15091615/

相关文章:

python - 根据其他模型字段自动更新 Django 模型

python - Django ORM : Joining QuerySets

django - 如何修复 Python Django 类型错误

python - 将数据保存到数据库时出错

python - 使用 Sqlite3 运行 Django Unittest 时缺少表

python - 文件从swift上传到django

Django 管理模板覆盖在生产环境中不起作用

python - Django的ImageField中如何重命名当前,清除和更改标签

python - 在 Django 模型中使用 save() 会产生 TypeError

Python runserver 错误加载 MySQLDB 模块 : undefined symbol: mysql_kill