【问题标题】:How to prevent duplicates when using ModelChoiceFilter in Django Filter and Wagtail在 Django Filter 和 Wagtail 中使用 ModelChoiceFilter 时如何防止重复
【发布时间】:2019-04-24 14:20:49
【问题描述】:

我正在尝试将过滤器与 Wagtail Page 模型和 Orderable 模型一起使用。但现在我的过滤器中有重复项。我该如何解决这样的问题?

我的代码:

class FieldPosition(Orderable):
    page                        = ParentalKey('PlayerDetailPage', on_delete=models.CASCADE, related_name='field_position_relationship')
    field_position              = models.CharField(max_length=3, choices=FIELD_POSITION_CHOICES, null=True)

    panels = [
        FieldPanel('field_position')
    ]

    def __str__(self):
        return self.get_field_position_display()



class PlayerDetailPage(Page):
    content_panels              = Page.content_panels + [
                                                        InlinePanel('field_position_relationship', label="Field position", max_num=3),
    ]


class PlayerDetailPageFilter(FilterSet):
    field_position_relationship          = filters.ModelChoiceFilter(queryset=FieldPosition.objects.all())

    class Meta:
        model = PlayerDetailPage
        fields = []

所以我要做的是创建一个过滤器,它使用来自FIELD_POSITION_CHOICES 的条目来过滤掉任何在 Wagtail 的内联面板中声明了此位置的页面。

如下图所示,过滤器正在通过,页面正在渲染。 (这些是包含 3 个字段位置列表的 2 页)。

所以第 1 页和第 2 页都有一个“Left Winger”条目,所以这是下拉列表中的两倍。过滤效果很好。

我能做些什么来防止这种情况发生?

解决方案应该是这样的(感谢 Harris):

我基本上每个页面字段位置都有一个FieldPosition 对象,因此它正确列出了所有对象。我怀疑我不应该在那里使用模型选择器,而是使用FIELD_POSITION_CHOICES 中的硬编码值列表,然后使用过滤器执行类似于PlayerDetailPage.objects.filter(field_position_relationship__field_position=str_field_position_choice) 的查询。但是 Django Filter 的做法是什么?

【问题讨论】:

    标签: django-models wagtail django-filter django-filters


    【解决方案1】:

    拉夫

    在我有限的简单化视图中,它看起来像

    class PlayerDetailPageFilter(FilterSet):
        field_position_relationship = filters.ModelChoiceFilter(queryset=FieldPosition.objects.all())
    

    将从 FieldPosition 返回所有对象,如果您在此处有 2 个“左翼”条目(一个用于第 1 页,一个用于第 2 页),那么这在您的列表中重复是有道理的。那么您是否尝试过使用 .distinct 过滤此列表查询集?也许像

    class PlayerDetailPageFilter(FilterSet):
        field_position_relationship = filters.ModelChoiceFilter(queryset=FieldPosition.objects.values('field_position').distinct())
    

    【讨论】:

    • 我找到了解决方案并在下面添加了答案。这个我没试过。
    【解决方案2】:

    经过反复试验,我找到了解决方案:

    过滤器:

    class PlayerDetailPageFilter(FilterSet):
        field_position_relationship__field_position     = filters.ChoiceFilter(choices=FIELD_POSITION_CHOICES)
    
        class Meta:
            model = PlayerDetailPage
            fields = []
    

    然后是这样的视图:

    context['filter_page'] = PlayerDetailPageFilter(request.GET, queryset=PlayerDetailPage.objects.all()
    

    通过 ParentalKey field_position_relationship__ 的相关名称访问 field_position

    然后使用 Django 过滤器 ChoiceFilter 我现在从选择列表中获取所有硬编码条目,并将它们与 PlayerDetailPage 查询集中的条目进行比较。

    在模板中,我可以使用 Django Filter 方法获取列表,然后循环查询集:

    <form action="" method="get">
    
    {{ filter_page.form.as_p }}
    
    <input type="submit" />
    </form>
    
    {% for obj in filter_page.qs %}
    {{ obj }} >
    {% endfor %}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-10
      • 2020-01-29
      • 2021-04-28
      • 1970-01-01
      • 1970-01-01
      • 2020-04-08
      • 2019-06-26
      • 2012-10-14
      相关资源
      最近更新 更多