将值转换为json内部的serve方法。鹡鸰

时间:2018-02-17 01:27:47

标签: wagtail

我真的试图找到我的问题的答案,但不知道该怎么办。我发现了以下问题,他们没有帮助我。 question1question2docs

我使用不同的函数获得了不同的值。有时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 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')
    ...

更新

很抱歉,如果我问过noob问题,但我是编程新手。 @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])

返回: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])

返回: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

返回: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

返回: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

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

正如我所说,我不知道这种转换是如何运作的,所以我试着猜测。

1 个答案:

答案 0 :(得分:4)

这里的重要教训是尝试立即解决一个问题。您正在尝试在构建一些JSON的同时处理从serve返回响应的问题,并且看起来您不会在任何地方找到答案,因为修复了上半部分问题只是导致你在下半场出错。

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

def serve(self, request):
    if request.is_ajax():
        return "hello world!"
    else:
        return super(ScreencastPage, self).serve(request)

这会失败,例如:'str' object has no attribute 'get'。这告诉我们返回一个字符串是错误的:无论我们返回什么对象,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。所以现在你要问:这里发生了什么变化?我的真实数据与“假冒”的不同之处有什么不同?数据?如果您不确定,请添加调试行以查看正在进行的操作:

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不知道如何处理这些对象。您需要将它们转换为基本值,例如dicts,这意味着指定每个单独字段在输出中的显示方式:

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)

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

  • 不要放弃你的代码并尝试别的东西;
  • 查看错误消息告诉您的内容,尤其是它来自哪个代码行;
  • 看看是否有办法将其简化为 成功的简单案例,然后按照自己的方式回到真正的解决方案。