在服务方法中将值转换为 json.鹡鸰 [英] Converting value to json inside serve method. Wagtail

查看:16
本文介绍了在服务方法中将值转换为 json.鹡鸰的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我真的很想找到问题的答案,但不知道该怎么办.我发现了以下问题,他们没有帮助我.question1问题2文档

I realy tried to find answer to my question, but don't know what should I do. I found following question and they didn't help me. question1, question2, docs

我使用不同的函数得到了不同的值.有时 None
有时 TypeError: 'method' 类型的对象不是 JSON 可序列化的
AttributeError: 'str' 对象没有属性 'status_code' 和 this
TypeError: 'method' 对象不可迭代

I got different values with different functions that I used. Sometimes None value
sometimes TypeError: Object of type 'method' is not JSON serializable
and AttributeError: 'str' object has no attribute 'status_code' and this
TypeError: 'method' object is not iterable

但我仍然没有找到解决我的问题的方法.这是我的 Page 模型,它有 InlinePanel 从另一个类中获取一些数据:

But i didn't still find solution to solve my problem. Here is my Page model it has InlinePanel that takes some data from another 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 这些是我使用的方式.

Sorry if I ask too noob questions, but I'm new in programming. @gasman these are the ways I used.

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' 对象不可迭代

2

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

Just changed loop from for pn in self.matches: to 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:GroupstageTournamentModel"类型的对象不是 JSON 可序列化的

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:视图 wagtail.wagtailcore.views.serve 未返回 HttpResponse 对象.它返回 None .

4

def serve(self, request):
    if request.is_ajax():
        data = [
            n.match for n in self.groupstage_screencast_relationship.all()
        ]
        return data

返回:AttributeError: 'list' 对象没有属性 '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() 缺少 1 个必需的位置参数:'o'

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

As I said, I do not know how this conversion works, so I tried to guess.

推荐答案

这里的重要教训是尝试一次解决一个问题.您正在尝试在构建一些 JSON 的同时处理从 serve 返回的响应,并且看起来您没有任何进展,因为解决问题的前半部分只会导致下半场你犯了一个错误.

The important lesson here is to try to solve one problem at once. You're trying to deal with returning a response from serve at the same time as constructing some JSON, and it doesn't look like you're getting anywhere because fixing the first half of the problem just leads you to an error in the second half.

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

Let's make sure we know how to return something from serve, even if it's just something useless:

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 属性.查看文档,我们可以看到它应该是一个 HttpResponse 对象:

This will fail with something like: 'str' object has no attribute 'get'. This tells us that returning a string is the wrong thing to do: whatever object we return, Wagtail is expecting it to have a get attribute. Looking at the documentation, we can see that it's supposed to be an HttpResponse object:

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) 结束.

This works, so now we know that whatever other stuff we do with JSON in this method, we need to end with return HttpResponse(some_result).

那么现在让我们引入 json.dumps.同样,让我们​​从一些虚假数据开始,以确保我们正确使用它:

So now let's bring in json.dumps. Again, let's start with some fake data to make sure we're using it right:

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)

希望这也有效,所以让我们引入真实数据:

Hopefully this works too, so let's bring in the real data:

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.所以现在你必须问:这里发生了什么变化?我的真实数据与假"数据有什么不同?如果您不确定,请添加调试行以查看发生了什么:

This now fails with something like: TypeError: Object of type 'GroupstageTournamentModel' is not JSON serializable. So now you have to ask: what's changed here? What's different about my real data from the 'fake' data? If you're not sure, add in a debugging line to see what's going on:

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,这意味着指定每个字段在输出中的显示方式:

The error message hopefully makes it clear: the value you're passing to json.dumps contains GroupstageTournamentModel objects, and JSON doesn't know how to deal with those. You need to convert them into basic values such as dicts, and that means specifying how each individual field is meant to appear in the output:

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)

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

In summary - when you encounter an error message:

  • 不要只是放弃你的代码而尝试其他的东西;
  • 看看错误消息告诉你什么,特别是它来自哪一行代码;
  • 看看是否有办法将其简化为确实成功的更简单的案例,然后再回到真正的解决方案.
  • don't just abandon your code and try something else;
  • look at what the error message is telling you, and especially, what line of code it's coming from;
  • see if there's a way to reduce it to a simpler case that does succeed, then work your way back up to the real solution.

这篇关于在服务方法中将值转换为 json.鹡鸰的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆