【问题标题】:How can I limit what m2m items are displayed in django template-side?如何限制 django 模板端显示的 m2m 项目?
【发布时间】:2015-10-28 22:12:13
【问题描述】:

我在限制 m2m 字段的视图中有一个查询集。查询似乎可以正常工作并获得正确的父对象,但是当我遍历模板中的 parent.object_set.all 时,我看到在技术上不包含在初始查询中的 m2m 对象(或者无论如何都不应该包含),但是现在包括在内,因为它们是父母的孩子 m2m object_set 的一部分。

尝试把这个放在一个更通用的例子中......我完全是在编造父母和孩子:

class Parent(models.Model):
    name = models.CharField(max_length=42)
    children = models.ManyToManyField(Child)

class Child(models.Model):
    ...
    # no, I'm not serious on this as a data structure, but for the example....
    male = models.BooleanField()
    female = models.BooleanField()

class ParentListView(ListView):
    ...
    def get_queryset(self):
        ...
        parents = Parent.objects.filter(children__male = True)

在模板中。

{% for parent in parents %}
    {{ parent.name }}
    {% for child in parent.child_set.all %}
        {% comment %}
            oops, I got all the children of this parent....I only want those that were male from the original queryset. I need the child_set to only be those that met the criteria in that first queryset. How do I accomplish this?
        {% endcomment %}
    {% endfor %}
{% endfor %} 

【问题讨论】:

  • 有些父母有男有女
  • 你不能纯粹在模板中做到这一点。您需要在视图中设置所需的子集或编写自定义模板标签来查找它们。

标签: django django-templates django-views django-queryset


【解决方案1】:

您不能使用 Django 模板语言提供过滤器参数。

在 Django 1.7+ 中,您可以在视图中定义查询集时使用 prefetch_related 和自定义 Prefetch 对象。

def get_queryset(self):
    ...
    parents = Parent.objects.filter(
        children__male=True
    ).prefetch_related(
        Prefetch('children', queryset=Child.objects.filter(male=True), to_attr='male_children')
    )

请注意,在上面的示例中,您可能需要使用distinct() 来防止每个男孩都有重复的父母。

我们已按照文档中的建议使用 to_attr 参数。在模板中,我们然后循环遍历男性孩子。

{% for parent in parents %}
    {{ parent.name }}
    {% for child in parent.male_children %}
        {{ child }}
    {% endfor %}
{% endfor %} 

【讨论】:

  • 太棒了。我还没有尝试过,但这将完全符合我的要求。感谢您的帮助。
  • 哦。并感谢您修复/编辑我的型号名称。我不确定 Person 来自哪里。
猜你喜欢
  • 2011-03-05
  • 2015-05-24
  • 1970-01-01
  • 2015-01-27
  • 2019-12-29
  • 2018-12-27
  • 2019-02-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多