以 10 为底的 int() 的无效文字:'RW' 将 Django 过滤器与 Wagtail 一起使用时
invalid literal for int() with base 10: 'RW' when using Django Filter with Wagtail
我正在尝试在 Wagtail Page 模型上集成过滤器(这基本上是一个完整的 Django 模型,更多信息请参见此处:http://docs.wagtail.io/en/v2.4/topics/pages.html)。
PlayerDetailPage 就像一个包含详细信息的 Post 页面,而 PlayerPage 就像一个博客页面,包含所有帖子的概览。
这里我想使用 Django Filter 过滤某些字段。但是,由于 Field Position 模型是一个内联模型并且抽象并通过 ParentalKey 连接,我不确定如何执行此操作。
如果您看到使用 ForeignKey 的 'agency' 字段,我可以使用 __ 在 Django-Filter 中简单地连接它,但我不知道如何使用 Wagtail InlinePanel 来做到这一点。
代码:
class FieldPosition(models.Model):
FIELD_POSITION_CHOICES = (
('GK', _('Goalkeeper')),
('LB', _('Left back')),
('LCD', _('Left central defender')),
('CD', _('Central defender')),
('RCD', _('Right central defender')),
('RB', _('Right back')),
('LWB', _('Left wing back')),
......
field_position = models.CharField(max_length=3, choices=FIELD_POSITION_CHOICES, null=True)
level = models.CharField(max_length=2, choices=FIELD_POSITION_LEVEL, null=True)
class Meta:
unique_together = ('field_position', 'level')
abstract = True
# Relationship between PlayerDetailPage and the FieldPosition model
class FieldPositionRelationship(Orderable, FieldPosition):
page = ParentalKey('PlayerDetailPage', on_delete=models.CASCADE, related_name='field_position')
class PlayerPage(Page):
# Overriding the Wagtail page model to add extra variables. This is the Wagtail way as per the creator
def get_context(self, request):
context = super(PlayerPage, self).get_context(request)
context['filter'] = PlayerDetailPageFilter(request.GET, queryset=PlayerDetailPage.objects.all())
return context
class PlayerDetailPage(Page):
club = models.ForeignKey('Clubs', null=True, blank=True, on_delete=models.SET_NULL, related_name='+')
content_panels = Page.content_panels + [
InlinePanel('field_position', label="Field position", max_num=3),
]
class PlayerDetailPageFilter(django_filters.FilterSet):
field_position = django_filters.filters.ModelMultipleChoiceFilter(field_name='field_position',
to_field_name='field_position', queryset=FieldPositionRelationship.objects.all())
class Meta:
model = PlayerDetailPage
fields = [ 'club__name', 'field_position' ]
在我的模板中,我这样做:
<form action="" method="get">
{{ filter.form.as_p }}
<input type="submit" />
{% for page in filter.qs %}
{% for i in page.field_position.all %}
{{ i.field_position }}
{% endfor %}
{% endfor %}
因此,当我遍历 field_position 时,我可以看到我声明的变量以及附加到页面模型的变量。但是,当我尝试使用过滤器时,我得到了这个回溯:
Traceback:
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/template/base.py" in _resolve_lookup
835. current = current[bit]
During handling of the above exception ('PlayerDetailPageFilter' object is not subscriptable), another exception occurred:
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
35. response = get_response(request)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
158. response = self.process_exception_by_middleware(e, request)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
156. response = response.render()
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/template/response.py" in render
106. self.content = self.rendered_content
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/template/response.py" in rendered_content
83. content = template.render(context, self._request)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/template/backends/django.py" in render
61. return self.template.render(context)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/template/base.py" in render
175. return self._render(context)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/test/utils.py" in instrumented_test_render
98. return self.nodelist.render(context)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/template/base.py" in render
943. bit = node.render_annotated(context)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/template/base.py" in render_annotated
910. return self.render(context)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/template/loader_tags.py" in render
155. return compiled_parent._render(context)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/test/utils.py" in instrumented_test_render
98. return self.nodelist.render(context)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/template/base.py" in render
943. bit = node.render_annotated(context)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/template/base.py" in render_annotated
910. return self.render(context)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/template/loader_tags.py" in render
67. result = block.nodelist.render(context)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/template/base.py" in render
943. bit = node.render_annotated(context)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/template/base.py" in render_annotated
910. return self.render(context)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/template/defaulttags.py" in render
161. values = self.sequence.resolve(context, True)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/template/base.py" in resolve
676. obj = self.var.resolve(context)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/template/base.py" in resolve
802. value = self._resolve_lookup(context)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/template/base.py" in _resolve_lookup
843. current = getattr(current, bit)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django_filters/filterset.py" in qs
237. qs = self.filter_queryset(qs)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django_filters/filterset.py" in filter_queryset
224. queryset = self.filters[name].filter(queryset, value)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django_filters/filters.py" in filter
251. qs = self.get_method(qs)(q)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/db/models/query.py" in filter
839. return self._filter_or_exclude(False, *args, **kwargs)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/db/models/query.py" in _filter_or_exclude
857. clone.query.add_q(Q(*args, **kwargs))
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/db/models/sql/query.py" in add_q
1253. clause, _ = self._add_q(q_object, self.used_aliases)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/db/models/sql/query.py" in _add_q
1271. current_negated, allow_joins, split_subq)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/db/models/sql/query.py" in _add_q
1277. split_subq=split_subq,
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/db/models/sql/query.py" in build_filter
1215. condition = self.build_lookup(lookups, col, value)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/db/models/sql/query.py" in build_lookup
1085. lookup = lookup_class(lhs, rhs)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/db/models/lookups.py" in __init__
18. self.rhs = self.get_prep_lookup()
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/db/models/fields/related_lookups.py" in get_prep_lookup
115. self.rhs = target_field.get_prep_value(self.rhs)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/db/models/fields/__init__.py" in get_prep_value
947. return int(value)
Exception Type: ValueError at /pages/players/
Exception Value: invalid literal for int() with base 10: 'RW'
所以问题出在这部分代码中:
class PlayerDetailPageFilter(django_filters.FilterSet):
field_position = django_filters.filters.ModelMultipleChoiceFilter(field_name='field_position',
to_field_name='field_position', queryset=FieldPositionRelationship.objects.all())
class Meta:
model = PlayerDetailPage
fields = [ 'club__name', 'field_position' ]
我指的是 field_position
,它是 FieldPositionRelationship
的 ID,所以它是一个整数。我 运行 我的查询集是一个字符串,这就是我抛出这个回溯的原因。
这种方法也是错误的,因为 ModelMultipleChoiceFilter
应该是 MultipleChoiceFilter
因为我只想要一个字段位置选项的硬编码列表。
正确的过滤器应该是:
class PlayerDetailPageFilter(FilterSet):
field_position_relationship__field_position = filters.ChoiceFilter(choices=FIELD_POSITION_CHOICES)
class Meta:
model = PlayerDetailPage
fields = []
我正在尝试在 Wagtail Page 模型上集成过滤器(这基本上是一个完整的 Django 模型,更多信息请参见此处:http://docs.wagtail.io/en/v2.4/topics/pages.html)。
PlayerDetailPage 就像一个包含详细信息的 Post 页面,而 PlayerPage 就像一个博客页面,包含所有帖子的概览。
这里我想使用 Django Filter 过滤某些字段。但是,由于 Field Position 模型是一个内联模型并且抽象并通过 ParentalKey 连接,我不确定如何执行此操作。
如果您看到使用 ForeignKey 的 'agency' 字段,我可以使用 __ 在 Django-Filter 中简单地连接它,但我不知道如何使用 Wagtail InlinePanel 来做到这一点。
代码:
class FieldPosition(models.Model):
FIELD_POSITION_CHOICES = (
('GK', _('Goalkeeper')),
('LB', _('Left back')),
('LCD', _('Left central defender')),
('CD', _('Central defender')),
('RCD', _('Right central defender')),
('RB', _('Right back')),
('LWB', _('Left wing back')),
......
field_position = models.CharField(max_length=3, choices=FIELD_POSITION_CHOICES, null=True)
level = models.CharField(max_length=2, choices=FIELD_POSITION_LEVEL, null=True)
class Meta:
unique_together = ('field_position', 'level')
abstract = True
# Relationship between PlayerDetailPage and the FieldPosition model
class FieldPositionRelationship(Orderable, FieldPosition):
page = ParentalKey('PlayerDetailPage', on_delete=models.CASCADE, related_name='field_position')
class PlayerPage(Page):
# Overriding the Wagtail page model to add extra variables. This is the Wagtail way as per the creator
def get_context(self, request):
context = super(PlayerPage, self).get_context(request)
context['filter'] = PlayerDetailPageFilter(request.GET, queryset=PlayerDetailPage.objects.all())
return context
class PlayerDetailPage(Page):
club = models.ForeignKey('Clubs', null=True, blank=True, on_delete=models.SET_NULL, related_name='+')
content_panels = Page.content_panels + [
InlinePanel('field_position', label="Field position", max_num=3),
]
class PlayerDetailPageFilter(django_filters.FilterSet):
field_position = django_filters.filters.ModelMultipleChoiceFilter(field_name='field_position',
to_field_name='field_position', queryset=FieldPositionRelationship.objects.all())
class Meta:
model = PlayerDetailPage
fields = [ 'club__name', 'field_position' ]
在我的模板中,我这样做:
<form action="" method="get">
{{ filter.form.as_p }}
<input type="submit" />
{% for page in filter.qs %}
{% for i in page.field_position.all %}
{{ i.field_position }}
{% endfor %}
{% endfor %}
因此,当我遍历 field_position 时,我可以看到我声明的变量以及附加到页面模型的变量。但是,当我尝试使用过滤器时,我得到了这个回溯:
Traceback:
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/template/base.py" in _resolve_lookup
835. current = current[bit]
During handling of the above exception ('PlayerDetailPageFilter' object is not subscriptable), another exception occurred:
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
35. response = get_response(request)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
158. response = self.process_exception_by_middleware(e, request)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
156. response = response.render()
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/template/response.py" in render
106. self.content = self.rendered_content
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/template/response.py" in rendered_content
83. content = template.render(context, self._request)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/template/backends/django.py" in render
61. return self.template.render(context)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/template/base.py" in render
175. return self._render(context)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/test/utils.py" in instrumented_test_render
98. return self.nodelist.render(context)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/template/base.py" in render
943. bit = node.render_annotated(context)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/template/base.py" in render_annotated
910. return self.render(context)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/template/loader_tags.py" in render
155. return compiled_parent._render(context)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/test/utils.py" in instrumented_test_render
98. return self.nodelist.render(context)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/template/base.py" in render
943. bit = node.render_annotated(context)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/template/base.py" in render_annotated
910. return self.render(context)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/template/loader_tags.py" in render
67. result = block.nodelist.render(context)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/template/base.py" in render
943. bit = node.render_annotated(context)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/template/base.py" in render_annotated
910. return self.render(context)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/template/defaulttags.py" in render
161. values = self.sequence.resolve(context, True)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/template/base.py" in resolve
676. obj = self.var.resolve(context)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/template/base.py" in resolve
802. value = self._resolve_lookup(context)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/template/base.py" in _resolve_lookup
843. current = getattr(current, bit)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django_filters/filterset.py" in qs
237. qs = self.filter_queryset(qs)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django_filters/filterset.py" in filter_queryset
224. queryset = self.filters[name].filter(queryset, value)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django_filters/filters.py" in filter
251. qs = self.get_method(qs)(q)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/db/models/query.py" in filter
839. return self._filter_or_exclude(False, *args, **kwargs)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/db/models/query.py" in _filter_or_exclude
857. clone.query.add_q(Q(*args, **kwargs))
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/db/models/sql/query.py" in add_q
1253. clause, _ = self._add_q(q_object, self.used_aliases)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/db/models/sql/query.py" in _add_q
1271. current_negated, allow_joins, split_subq)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/db/models/sql/query.py" in _add_q
1277. split_subq=split_subq,
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/db/models/sql/query.py" in build_filter
1215. condition = self.build_lookup(lookups, col, value)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/db/models/sql/query.py" in build_lookup
1085. lookup = lookup_class(lhs, rhs)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/db/models/lookups.py" in __init__
18. self.rhs = self.get_prep_lookup()
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/db/models/fields/related_lookups.py" in get_prep_lookup
115. self.rhs = target_field.get_prep_value(self.rhs)
File "/Users/rafrasenberg/myoden/lib/python3.6/site-packages/django/db/models/fields/__init__.py" in get_prep_value
947. return int(value)
Exception Type: ValueError at /pages/players/
Exception Value: invalid literal for int() with base 10: 'RW'
所以问题出在这部分代码中:
class PlayerDetailPageFilter(django_filters.FilterSet):
field_position = django_filters.filters.ModelMultipleChoiceFilter(field_name='field_position',
to_field_name='field_position', queryset=FieldPositionRelationship.objects.all())
class Meta:
model = PlayerDetailPage
fields = [ 'club__name', 'field_position' ]
我指的是 field_position
,它是 FieldPositionRelationship
的 ID,所以它是一个整数。我 运行 我的查询集是一个字符串,这就是我抛出这个回溯的原因。
这种方法也是错误的,因为 ModelMultipleChoiceFilter
应该是 MultipleChoiceFilter
因为我只想要一个字段位置选项的硬编码列表。
正确的过滤器应该是:
class PlayerDetailPageFilter(FilterSet):
field_position_relationship__field_position = filters.ChoiceFilter(choices=FIELD_POSITION_CHOICES)
class Meta:
model = PlayerDetailPage
fields = []