如何过滤 ManyToMany 字段反向引用中的对象?

How to filter objects in ManyToMany field back reference?

我想像这样列出所有已发布的标签和已发布的帖子:

Tag1
├── first-post
└── second-post
Tag2
├── third-post
└── fourth-post

我有 TagPost 个这样的模型:

class Tag(models.Model):
    name = models.CharField(max_length=16)
    is_published = models.BooleanField(default=True)

class Post(models.Model):
    title = models.CharField(max_length=192)
    tags = models.ManyToManyField(Tag, related_name='posts')    
    is_published = models.BooleanField(default=True)

我有一个将标签传递给模板的上下文处理器:

def tags(request):
    published_tags = Tag.objects\
        .filter(is_published=True)\
        .exclude(posts=None)\
        .order_by('name')
    return {'tags': published_tags}

我在模板中列出标签和帖子是这样的:

{% for tag in tags %}
    <h1>{{ tag.name }}</h1>
    {% for post in tag.posts.all %}
        <li>
            <a href="{{ post.get_absolute_url }}">{{ post.title }}</a>
        </li>
    {% endfor %}
{% endfor %}

我可以通过 is_published 过滤标签。如何在标签 (Tag.posts)?

的反向引用中通过 is_published 过滤 posts

我不想 return 两个名为 tags 和 `posts' 的查询集。

我是这样做的:

def tags(request):
    published_tags = Tag.objects\
        .filter(is_published=True, posts__is_published=True)\
        .exclude(posts=None)\
        .order_by('name')\
        .distinct()
    return {'tags': published_tags}

ps: https://en.wikipedia.org/wiki/Rubber_duck_debugging