在serve方法中将值转换为json。鹡鸰

kha*_*hin 0 wagtail

我确实试图找到问题的答案,但不知道该怎么办。我发现了以下问题,但他们没有帮助我。问题1问题2文档

\n\n

我使用的不同函数得到了不同的值。有时None
\nTypeError: Object of type \'method\' is not JSON serializable
有时\nAttributeError: \'str\' object has no attribute \'status_code\'和\n而这个
\nTypeError: \'method\' object is not iterable

\n\n

但我仍然没有找到解决我的问题的解决方案。\n这是我的页面模型,它InlinePanel从另一个类获取一些数据:

\n\n
class ScreencastPage(Page):\n    content_panels = Page.content_panels + [\n        InlinePanel(\n            \'groupstage_screencast_relationship\', label="Choose Teams",\n            panels=None, max_num=2),\n    ]\n\n    parent_page_types = [\'home.HomePage\']\n\n    def matches(self):\n        matches = [\n            n.match for n in self.groupstage_screencast_relationship.all()\n        ]\n\n        return matches\n\n    def serve(self, request):\n        if request.is_ajax():\n            # TODO Convert self.mathes to JSON and return it\n        else:\n            return super(ScreencastPage, self).serve(request)\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是与我相关的模型ScreencastPage

\n\n
@register_snippet\nclass GroupstageTournamentModel(ClusterableModel):\n    number = models.PositiveSmallIntegerField(\n        verbose_name="Match \xe2\x84\x96:")\n    starts_at = models.DateTimeField()\n    # Team 1\n    team_1 = models.ForeignKey(\n        TeamRooster,\n        null=True, verbose_name=\'Erste Team\',\n        on_delete=models.SET_NULL,\n        related_name="+",\n    )\n    team_1_dress = ColorField(blank=True, verbose_name=\'Dress\')\n    team_1_first_halftime_score = models.PositiveSmallIntegerField(blank=True, default=0, verbose_name=\'Resultat 1. HZ\')\n    team_1_first_halftime_point = models.PositiveSmallIntegerField(blank=True, default=0, verbose_name=\'Punkte 1. HZ\')\n    ...\n
Run Code Online (Sandbox Code Playgroud)\n\n

更新

\n\n

抱歉,如果我问得太菜鸟问题,但我是编程新手。@gasman 这些是我使用的方法。

\n\n

1

\n\n
def serve(self, request):\n    if request.is_ajax():\n        lst = []\n        d = {}\n        for pn in self.matches:\n            d[\'mpn\']=pn\n            lst.append(d)\n        return json.dumps([dict(mpn=pn) for pn in lst])\n
Run Code Online (Sandbox Code Playgroud)\n\n

返回:TypeError: \'method\' object is not iterable

\n\n

2

\n\n

刚刚将循环从 更改for pn in self.matches:for pn in self.matches():

\n\n
def serve(self, request):\n    if request.is_ajax():\n        lst = []\n        d = {}\n        for pn in self.matches():\n            d[\'mpn\']=pn\n            lst.append(d)\n        return json.dumps([dict(mpn=pn) for pn in lst])\n
Run Code Online (Sandbox Code Playgroud)\n\n

返回:TypeError: Object of type \'GroupstageTournamentModel\' is not JSON serializable

\n\n

3

\n\n
def serve(self, request):\n    if request.is_ajax():\n        if isinstance(self.matches, (list, dict, str, int, float, bool, type(None))):\n            data = JSONEncoder.default(self.matches())\n            return data\n        elif \'_python_object\' in self.matches():\n            data = pickle.loads(str(self.matches[\'_python_object\']))\n            return data\n
Run Code Online (Sandbox Code Playgroud)\n\n

返回:ValueError: The view wagtail.wagtailcore.views.serve didn\'t return an HttpResponse object. It returned None instead.

\n\n

4

\n\n
def serve(self, request):\n    if request.is_ajax():\n        data = [\n            n.match for n in self.groupstage_screencast_relationship.all()\n        ]\n        return data\n
Run Code Online (Sandbox Code Playgroud)\n\n

返回:AttributeError: \'list\' object has no attribute \'status_code\'

\n\n

5

\n\n
def serve(self, request):\n    if request.is_ajax():\n        data = [\n            n.match for n in self.groupstage_screencast_relationship.all()\n        ]\n        if isinstance(data, (list, dict, str, int, float, bool, type(None))):\n            conv_data = json.JSONEncoder.default(data)\n            return conv_data\n
Run Code Online (Sandbox Code Playgroud)\n\n

返回:TypeError: default() missing 1 required positional argument: \'o\'

\n\n

正如我所说,我不知道这种转换是如何进行的,所以我尝试猜测。

\n

gas*_*man 5

这里重要的一课是尝试立即解决一个问题。您试图serve在构建一些 JSON 的同时处理返回响应,但看起来您并没有取得任何进展,因为解决问题的前半部分只会导致您在后半部分出错。

让我们确保我们知道如何从返回一些东西serve,即使它只是一些无用的东西:

def serve(self, request):
    if request.is_ajax():
        return "hello world!"
    else:
        return super(ScreencastPage, self).serve(request)
Run Code Online (Sandbox Code Playgroud)

这将失败,并出现类似以下内容:'str' object has no attribute 'get'。这告诉我们,返回字符串是错误的做法:无论我们返回什么对象,Wagtail 都期望它有一个get属性。查看文档,我们可以看到它应该是一个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)
Run Code Online (Sandbox Code Playgroud)

这是可行的,所以现在我们知道无论我们在此方法中使用 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)
Run Code Online (Sandbox Code Playgroud)

希望这也能起作用,所以让我们引入真实的数据:

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)
Run Code Online (Sandbox Code Playgroud)

现在失败了,如下所示:TypeError: Object of type 'GroupstageTournamentModel' is not JSON serializable。所以现在你必须问:这里发生了什么变化?我的真实数据与“假”数据有什么不同?如果您不确定,请添加调试行以查看发生了什么:

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)
Run Code Online (Sandbox Code Playgroud)

希望错误消息能够清楚地表明:您传递给的值包含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)
Run Code Online (Sandbox Code Playgroud)

总之 - 当您遇到错误消息时:

  • 不要只是放弃你的代码并尝试其他东西;
  • 查看错误消息告诉您什么,尤其是它来自哪一行代码;
  • 看看是否有办法将其简化为成功的更简单的情况然后再回到真正的解决方案。