在Django筛选器和Wagtail中使用ModelChoiceFilter时如何防止重复 [英] How to prevent duplicates when using ModelChoiceFilter in Django Filter and Wagtail
问题描述
我正在尝试对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屋!