在Django筛选器和Wagtail中使用ModelChoiceFilter时如何防止重复 [英] How to prevent duplicates when using ModelChoiceFilter in Django Filter and Wagtail

查看:142
本文介绍了在Django筛选器和Wagtail中使用ModelChoiceFilter时如何防止重复的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试对Wagtail Page模型和Orderable模型使用过滤器.但是我现在在过滤器中得到了重复项.我该如何解决这样的问题?

I am trying to use filters with a Wagtail Page model and a Orderable model. But I get duplicates in my filter now. How can I solve something like this?

我的代码:

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中的条目过滤掉在Wa中的嵌入式面板中声明了具有此位置的任何页面.

So what I am trying to do is create a filter which uses the entries from FIELD_POSITION_CHOICES to filter out any page that has this position declared in the inline panel in Wagtail.

如下面的图片所示,过滤器通过并且页面正在呈现. (这些是2页,列出3个字段的位置).

As you can see in the picture down below, the filters are coming through and the page is being rendered. (These are 2 pages with a list of 3 field positions).

因此,第1页和第2页都具有"Left Winger"条目,因此这是下拉菜单中的两倍.过滤效果很好.

So Page 1 and Page 2 both have a "Left Winger" entry, so this is double in the dropdown. The filtering works perfectly fine.

我可以采取什么措施来防止这种情况?

What can I do to prevent this?

解决方案应该是这样的(为此向哈里斯致谢):

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

I basically have one FieldPosition object per page-field position, so it's listing all of the objects correctly. I suspect I should not use the model chooser there, but a list of the hard coded values in FIELD_POSITION_CHOICES and then a filter to execute a query that looks something like PlayerDetailPage.objects.filter(field_position_relationship__field_position=str_field_position_choice). But what is the Django Filter way of doing this?

推荐答案

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

I found the solution after some trial and error:

过滤器:

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.

By accessing the field_position through the related name of the ParentalKey field_position_relationship with __.

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

Then using the Django Filter ChoiceFilter I get all the hard-coded entries now from the choice list and compare them against the entries inside the PlayerDetailPage query set.

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

In the template I can get the list using the Django Filter method and then just looping through the query set:

<form action="" method="get">

{{ filter_page.form.as_p }}

<input type="submit" />
</form>

{% for obj in filter_page.qs %}
{{ obj }} >
{% endfor %}

这篇关于在Django筛选器和Wagtail中使用ModelChoiceFilter时如何防止重复的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆