【问题标题】:Return all model results, but filter out the ManyToManyFields返回所有模型结果,但过滤掉 ManyToManyFields
【发布时间】:2021-04-03 15:53:55
【问题描述】:

我正在尝试过滤掉模型中的结果,以便所有字段都返回,但我只能过滤模型中的一个 ManyToManyField。我只希望它在页面上过滤掉,而不是在管理员中。

我找到了一些关于多对多过滤的重要信息,但由于某种原因,在这种特殊情况下没有任何帮助。所以我想我要么做错了,要么我错过了一个重要的搜索词。我已经尝试在模型、视图和模板中进行过滤。

这是一个帮助解释的最小示例:

# models.py
class Foo(models.Model):
    name = models.CharField(unique=True, max_length=255)
    bars = models.ManyToManyField(Bar)

class Bar(models.Model):
    thing = models.CharField(max_length=12)
    is_public = models.BooleanField(default=False)


# views.py
class FooDetail(DetailView):
    def get_queryset(self):
        # Would I filter in here?
        return super(FooDetail, self).get_queryset()

我希望 Foo 模型返回所有​​ foos,但对于每个 foo 仅包含 bars,这对于 is_public 是正确的 我在哪里过滤掉 Foo 模型的 Bar 结果?

我找到了this question which is basically what I'm asking,但答案是针对该问题的,并显示它已在序列化程序中过滤。所以我不明白如何/在哪里应用这个答案,我没有做任何序列化。 (我应该是吗?)

【问题讨论】:

    标签: django django-views


    【解决方案1】:

    您可以使用Prefetch() objects [Django docs] 并传递queryset 关键字参数来执行此操作:

    from django.db.models import Prefetch
    
    foo_queryset = Foo.objects.prefetch_related(
        Prefetch(
            'bar_set',
            queryset=Bar.objects.filter(is_public=True),
            to_attr='public_bars'
        )
    )
    

    现在您可以使用以下方法访问公开的相关Bar 实例:

    for foo in foo_queryset:
        print(foo.public_bars)
    

    【讨论】:

      猜你喜欢
      • 2014-08-13
      • 2012-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-08
      • 2018-03-05
      • 2020-02-12
      相关资源
      最近更新 更多