在 Django Filter 和 Wagtail 中使用 ModelChoiceFilter 时如何防止重复
How to prevent duplicates when using ModelChoiceFilter in Django Filter and Wagtail
我正在尝试将过滤器与 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 的做法是什么?
拉夫
在我有限的简单视图中,它看起来像
class PlayerDetailPageFilter(FilterSet):
field_position_relationship = filters.ModelChoiceFilter(queryset=FieldPosition.objects.all())
将 return 来自 FieldPosition 的所有对象,如果您在此处有 2 个 'left wing' 条目(一个用于第 1 页,一个用于第 2 页),那么这将是有意义的在您的列表中重复。那么您是否尝试过使用 .distinct 过滤此列表查询集?也许像
class PlayerDetailPageFilter(FilterSet):
field_position_relationship = filters.ModelChoiceFilter(queryset=FieldPosition.objects.values('field_position').distinct())
经过反复试验,我找到了解决方案:
过滤器:
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 %}
我正在尝试将过滤器与 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 的做法是什么?
拉夫
在我有限的简单视图中,它看起来像
class PlayerDetailPageFilter(FilterSet):
field_position_relationship = filters.ModelChoiceFilter(queryset=FieldPosition.objects.all())
将 return 来自 FieldPosition 的所有对象,如果您在此处有 2 个 'left wing' 条目(一个用于第 1 页,一个用于第 2 页),那么这将是有意义的在您的列表中重复。那么您是否尝试过使用 .distinct 过滤此列表查询集?也许像
class PlayerDetailPageFilter(FilterSet):
field_position_relationship = filters.ModelChoiceFilter(queryset=FieldPosition.objects.values('field_position').distinct())
经过反复试验,我找到了解决方案:
过滤器:
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 %}