在 serve 方法中将值转换为 json。鹡鸰
Converting value to json inside serve method. Wagtail
我真的很想找到我的问题的答案,但不知道该怎么办。我发现了以下问题,但他们没有帮助我。 question1, , docs
我使用的不同函数得到了不同的值。有时None
值
有时 TypeError: Object of type 'method' is not JSON serializable
和
AttributeError: 'str' object has no attribute 'status_code'
和这个
TypeError: 'method' object is not iterable
但我仍然没有找到解决问题的方法。
这是我的页面模型,它有 InlinePanel
从另一个 class:
获取一些数据
class ScreencastPage(Page):
content_panels = Page.content_panels + [
InlinePanel(
'groupstage_screencast_relationship', label="Choose Teams",
panels=None, max_num=2),
]
parent_page_types = ['home.HomePage']
def matches(self):
matches = [
n.match for n in self.groupstage_screencast_relationship.all()
]
return matches
def serve(self, request):
if request.is_ajax():
# TODO Convert self.mathes to JSON and return it
else:
return super(ScreencastPage, self).serve(request)
这是与我的ScreencastPage
相关的模型
@register_snippet
class GroupstageTournamentModel(ClusterableModel):
number = models.PositiveSmallIntegerField(
verbose_name="Match №:")
starts_at = models.DateTimeField()
# Team 1
team_1 = models.ForeignKey(
TeamRooster,
null=True, verbose_name='Erste Team',
on_delete=models.SET_NULL,
related_name="+",
)
team_1_dress = ColorField(blank=True, verbose_name='Dress')
team_1_first_halftime_score = models.PositiveSmallIntegerField(blank=True, default=0, verbose_name='Resultat 1. HZ')
team_1_first_halftime_point = models.PositiveSmallIntegerField(blank=True, default=0, verbose_name='Punkte 1. HZ')
...
更新
对不起,如果我问的问题太菜鸟了,但我是编程新手。 @gasman 这些是我使用的方式。
1
def serve(self, request):
if request.is_ajax():
lst = []
d = {}
for pn in self.matches:
d['mpn']=pn
lst.append(d)
return json.dumps([dict(mpn=pn) for pn in lst])
returns: TypeError: 'method' object is not iterable
2
刚刚将循环从 for pn in self.matches:
更改为 for pn in self.matches():
def serve(self, request):
if request.is_ajax():
lst = []
d = {}
for pn in self.matches():
d['mpn']=pn
lst.append(d)
return json.dumps([dict(mpn=pn) for pn in lst])
returns: TypeError: Object of type 'GroupstageTournamentModel' is not JSON serializable
3
def serve(self, request):
if request.is_ajax():
if isinstance(self.matches, (list, dict, str, int, float, bool, type(None))):
data = JSONEncoder.default(self.matches())
return data
elif '_python_object' in self.matches():
data = pickle.loads(str(self.matches['_python_object']))
return data
returns: ValueError: The view wagtail.wagtailcore.views.serve didn't return an HttpResponse object. It returned None instead.
4
def serve(self, request):
if request.is_ajax():
data = [
n.match for n in self.groupstage_screencast_relationship.all()
]
return data
returns: AttributeError: 'list' object has no attribute 'status_code'
5
def serve(self, request):
if request.is_ajax():
data = [
n.match for n in self.groupstage_screencast_relationship.all()
]
if isinstance(data, (list, dict, str, int, float, bool, type(None))):
conv_data = json.JSONEncoder.default(data)
return conv_data
returns: TypeError: default() missing 1 required positional argument: 'o'
正如我所说,我不知道这种转换是如何进行的,所以我试着猜测。
这里重要的一课是尝试一次解决一个问题。您正在尝试处理 return 来自 serve
的响应,同时构建一些 JSON,但看起来您没有任何进展,因为修复了第一个一半的问题只会导致你在后半部分出错。
让我们确保我们知道如何从 serve
中 return 某些东西 ,即使它只是一些无用的东西:
def serve(self, request):
if request.is_ajax():
return "hello world!"
else:
return super(ScreencastPage, self).serve(request)
这将失败并显示如下内容:'str' object has no attribute 'get'
。这告诉我们 return 字符串是错误的做法:无论我们 return 什么对象,Wagtail 都期望它具有 get
属性。查看the documentation,我们可以看到它应该是一个HttpResponse
对象:
from django.http import HttpResponse
def serve(self, request):
if request.is_ajax():
return HttpResponse("hello world!")
else:
return super(ScreencastPage, self).serve(request)
这行得通,所以现在我们知道无论我们在这个方法中使用 JSON 做什么其他事情,我们都需要以 return HttpResponse(some_result)
.
结束
现在让我们引入 json.dumps
。同样,让我们从一些假数据开始,以确保我们正确使用它:
import json
from django.http import HttpResponse
def serve(self, request):
if request.is_ajax():
result = ['first match', 'second match']
json_output = json.dumps(result)
return HttpResponse(json_output)
else:
return super(ScreencastPage, self).serve(request)
希望这也能奏效,让我们引入真实数据:
import json
from django.http import HttpResponse
def serve(self, request):
if request.is_ajax():
result = self.matches()
json_output = json.dumps(result)
return HttpResponse(json_output)
else:
return super(ScreencastPage, self).serve(request)
这现在失败了:TypeError: Object of type 'GroupstageTournamentModel' is not JSON serializable
。所以现在你不得不问:这里发生了什么变化?我的真实数据与 'fake' 数据有何不同?如果您不确定,请添加调试行以查看发生了什么:
import json
from django.http import HttpResponse
def serve(self, request):
if request.is_ajax():
result = self.matches()
print(result) # this output will appear in the terminal / command prompt
json_output = json.dumps(result)
return HttpResponse(json_output)
else:
return super(ScreencastPage, self).serve(request)
错误消息希望能清楚地表明:您传递给 json.dumps
的值包含 GroupstageTournamentModel
个对象,而 JSON 不知道如何处理这些对象。您需要将它们转换为基本值,例如字典,这意味着指定每个字段在输出中的显示方式:
def serve(self, request):
if request.is_ajax():
result = [
{
'number': match.number,
'team1': match.team_1.name,
# ...
}
for match in self.matches()
]
json_output = json.dumps(result)
return HttpResponse(json_output)
else:
return super(ScreencastPage, self).serve(request)
总结 - 当您遇到错误信息时:
- 不要只是放弃您的代码并尝试其他东西;
- 查看错误消息告诉您的内容,尤其是它来自哪一行代码;
- 看看是否有办法将其简化为确实成功的更简单的情况,然后再回到真正的解决方案。
我真的很想找到我的问题的答案,但不知道该怎么办。我发现了以下问题,但他们没有帮助我。 question1,
我使用的不同函数得到了不同的值。有时None
值
有时 TypeError: Object of type 'method' is not JSON serializable
和
AttributeError: 'str' object has no attribute 'status_code'
和这个
TypeError: 'method' object is not iterable
但我仍然没有找到解决问题的方法。
这是我的页面模型,它有 InlinePanel
从另一个 class:
class ScreencastPage(Page):
content_panels = Page.content_panels + [
InlinePanel(
'groupstage_screencast_relationship', label="Choose Teams",
panels=None, max_num=2),
]
parent_page_types = ['home.HomePage']
def matches(self):
matches = [
n.match for n in self.groupstage_screencast_relationship.all()
]
return matches
def serve(self, request):
if request.is_ajax():
# TODO Convert self.mathes to JSON and return it
else:
return super(ScreencastPage, self).serve(request)
这是与我的ScreencastPage
@register_snippet
class GroupstageTournamentModel(ClusterableModel):
number = models.PositiveSmallIntegerField(
verbose_name="Match №:")
starts_at = models.DateTimeField()
# Team 1
team_1 = models.ForeignKey(
TeamRooster,
null=True, verbose_name='Erste Team',
on_delete=models.SET_NULL,
related_name="+",
)
team_1_dress = ColorField(blank=True, verbose_name='Dress')
team_1_first_halftime_score = models.PositiveSmallIntegerField(blank=True, default=0, verbose_name='Resultat 1. HZ')
team_1_first_halftime_point = models.PositiveSmallIntegerField(blank=True, default=0, verbose_name='Punkte 1. HZ')
...
更新
对不起,如果我问的问题太菜鸟了,但我是编程新手。 @gasman 这些是我使用的方式。
1
def serve(self, request):
if request.is_ajax():
lst = []
d = {}
for pn in self.matches:
d['mpn']=pn
lst.append(d)
return json.dumps([dict(mpn=pn) for pn in lst])
returns: TypeError: 'method' object is not iterable
2
刚刚将循环从 for pn in self.matches:
更改为 for pn in self.matches():
def serve(self, request):
if request.is_ajax():
lst = []
d = {}
for pn in self.matches():
d['mpn']=pn
lst.append(d)
return json.dumps([dict(mpn=pn) for pn in lst])
returns: TypeError: Object of type 'GroupstageTournamentModel' is not JSON serializable
3
def serve(self, request):
if request.is_ajax():
if isinstance(self.matches, (list, dict, str, int, float, bool, type(None))):
data = JSONEncoder.default(self.matches())
return data
elif '_python_object' in self.matches():
data = pickle.loads(str(self.matches['_python_object']))
return data
returns: ValueError: The view wagtail.wagtailcore.views.serve didn't return an HttpResponse object. It returned None instead.
4
def serve(self, request):
if request.is_ajax():
data = [
n.match for n in self.groupstage_screencast_relationship.all()
]
return data
returns: AttributeError: 'list' object has no attribute 'status_code'
5
def serve(self, request):
if request.is_ajax():
data = [
n.match for n in self.groupstage_screencast_relationship.all()
]
if isinstance(data, (list, dict, str, int, float, bool, type(None))):
conv_data = json.JSONEncoder.default(data)
return conv_data
returns: TypeError: default() missing 1 required positional argument: 'o'
正如我所说,我不知道这种转换是如何进行的,所以我试着猜测。
这里重要的一课是尝试一次解决一个问题。您正在尝试处理 return 来自 serve
的响应,同时构建一些 JSON,但看起来您没有任何进展,因为修复了第一个一半的问题只会导致你在后半部分出错。
让我们确保我们知道如何从 serve
中 return 某些东西 ,即使它只是一些无用的东西:
def serve(self, request):
if request.is_ajax():
return "hello world!"
else:
return super(ScreencastPage, self).serve(request)
这将失败并显示如下内容:'str' object has no attribute 'get'
。这告诉我们 return 字符串是错误的做法:无论我们 return 什么对象,Wagtail 都期望它具有 get
属性。查看the documentation,我们可以看到它应该是一个HttpResponse
对象:
from django.http import HttpResponse
def serve(self, request):
if request.is_ajax():
return HttpResponse("hello world!")
else:
return super(ScreencastPage, self).serve(request)
这行得通,所以现在我们知道无论我们在这个方法中使用 JSON 做什么其他事情,我们都需要以 return HttpResponse(some_result)
.
现在让我们引入 json.dumps
。同样,让我们从一些假数据开始,以确保我们正确使用它:
import json
from django.http import HttpResponse
def serve(self, request):
if request.is_ajax():
result = ['first match', 'second match']
json_output = json.dumps(result)
return HttpResponse(json_output)
else:
return super(ScreencastPage, self).serve(request)
希望这也能奏效,让我们引入真实数据:
import json
from django.http import HttpResponse
def serve(self, request):
if request.is_ajax():
result = self.matches()
json_output = json.dumps(result)
return HttpResponse(json_output)
else:
return super(ScreencastPage, self).serve(request)
这现在失败了:TypeError: Object of type 'GroupstageTournamentModel' is not JSON serializable
。所以现在你不得不问:这里发生了什么变化?我的真实数据与 'fake' 数据有何不同?如果您不确定,请添加调试行以查看发生了什么:
import json
from django.http import HttpResponse
def serve(self, request):
if request.is_ajax():
result = self.matches()
print(result) # this output will appear in the terminal / command prompt
json_output = json.dumps(result)
return HttpResponse(json_output)
else:
return super(ScreencastPage, self).serve(request)
错误消息希望能清楚地表明:您传递给 json.dumps
的值包含 GroupstageTournamentModel
个对象,而 JSON 不知道如何处理这些对象。您需要将它们转换为基本值,例如字典,这意味着指定每个字段在输出中的显示方式:
def serve(self, request):
if request.is_ajax():
result = [
{
'number': match.number,
'team1': match.team_1.name,
# ...
}
for match in self.matches()
]
json_output = json.dumps(result)
return HttpResponse(json_output)
else:
return super(ScreencastPage, self).serve(request)
总结 - 当您遇到错误信息时:
- 不要只是放弃您的代码并尝试其他东西;
- 查看错误消息告诉您的内容,尤其是它来自哪一行代码;
- 看看是否有办法将其简化为确实成功的更简单的情况,然后再回到真正的解决方案。