发布到我的 Django API 时:errorcom.google.gson.JsonParseException: 无法解析 json

Posted

技术标签:

【中文标题】发布到我的 Django API 时:errorcom.google.gson.JsonParseException: 无法解析 json【英文标题】:When posting to my Django API : errorcom.google.gson.JsonParseException: unable to parse json 【发布时间】:2015-08-03 18:17:12 【问题描述】:

谁能告诉我我在这篇文章中做错了什么?

我怀疑我错误地发布到我的 django API。我基本上有一个 Question 对象,其中包含一个 Answers 数组的字段。我可以在没有答案的情况下正确发布,但是当我尝试为 answers 添加 JsonArray 时,发布失败并出现无法解析错误。

LogCat 摘录

05-21 00:12:52.875  15720-15720/com.pipit.waffle D/ConnectToBackend﹕ "text":"gf or ed","answers":["text":"gf","votes":0,"id":null,"text":"ed","votes":0,"id":null],"user_id":"temp user id"
05-21 00:12:52.875  15720-15720/com.pipit.waffle D/ConnectToBackend﹕ postQuestion called with MY API and has errorcom.google.gson.JsonParseException: unable to parse json
05-21 00:12:52.875  15720-15720/com.pipit.waffle D/ConnectToBackend﹕ postQuestion returns result with NULL

Django 端

序列化器.py

class EmbeddedAnswerSerializer(serializers.ModelSerializer):
    votes = serializers.IntegerField(read_only=True)
    picture = serializers.ImageField(read_only=True)
    class Meta:
        model = Answer
        fields = ('id', 'picture', 'text', 'votes',)


class QuestionSerializer(serializers.ModelSerializer):
    answers = EmbeddedAnswerSerializer(many=True, source='answer_set')

    class Meta:
        model = Question
        fields = ('id', 'answers', 'created_at', 'text', 'user_id',)


class AnswerSerializer(serializers.ModelSerializer):
    text = serializers.CharField(read_only=True)
    vote = serializers.BooleanField(required=True)
    picture = serializers.ImageField(read_only=True)
    votes = serializers.IntegerField(read_only=True)

models.py

class Question(models.Model):
    user_id = models.CharField(max_length=36)
    text = models.CharField(max_length=140)
    created_at = models.DateTimeField(auto_now_add=True)

    def __unicode__(self):
        return u'Question #'.format(self.pk)

class Answer(models.Model):
    picture = models.ImageField(("Picture"), upload_to=upload_pic_to, blank=True)
    question = models.ForeignKey(Question)
    text = models.CharField(max_length=25)
    votes = models.IntegerField(default=0)

    def __unicode__(self):
        return u'Answer to question  ( votes)'.format(self.question_id, self.votes)

客户端 (安卓)

public static void postQuestion(final Context mcontext, Question mquestion)
        JsonArray answerarray = new JsonArray();
        JsonObject answerjson = new JsonObject();
        JsonObject answerjson2 = new JsonObject();
        answerjson.addProperty("text", mquestion.getChoices().get(0).getAnswerBody());
        answerjson2.addProperty("text", mquestion.getChoices().get(1).getAnswerBody());
        answerjson.addProperty("votes", 0);
        answerjson2.addProperty("votes", 0);
        answerjson.addProperty("id", mquestion.getId());
        answerjson2.addProperty("id", mquestion.getId());
        answerarray.add(answerjson);
        answerarray.add(answerjson2);

        JsonObject json = new JsonObject();
        json.addProperty("text", mquestion.getQuestionBody());
        json.add("answers", answerarray);
        json.addProperty("user_id", "temp user id");
        final String url = "my endpoint";
        Ion.with(mcontext) //Ion Koush is just a library for making async android requests to a URL  - doubt this is the problem
                .load(url)
                .setJsonObjectBody(json)
                .asJsonObject()
                .setCallback(new FutureCallback<JsonObject>() 
                    @Override
                    public void onCompleted(Exception e, JsonObject result) 
                        if (e != null)
                            Log.d("ConnectToBackend", "postQuestion called with "+url+" and has error" + e.toString());
                            if (result==null)
                                Log.d("ConnectToBackend", "postQuestion returns result with NULL");
                            
                        
                        else
                            //Do Stuff
                        

                    
                );
    

这是一个成功 GET 到同一端点的示例

"id":5,"answers":["id":10,"picture":"someurl","text":"microsoft","votes":0,"id":9,"picture":"someurl","text":"apple","votes":0],"created_at":"2015-03-15T04:14:00.782903Z","text":"MicroSoft or Apple","user_id":"8"

【问题讨论】:

source='answer_set' 您不能在 QuestionSerializer 中使用 answer_set,因为 'answer_set' 不是 Question 模型的属性。 【参考方案1】:

你确定它实际上不是一个成功的字符串而不是字典吗?我在Django端遇到过这个问题,对Android了解不多。

使用 python 会是:

import json
your_dict = ...

# this stringifies the dict
json.dumps(your_dict)

我知道您正在客户端上执行此操作,因此上面的代码不会是您的答案,但这是一个想法,希望对您有所帮助!

【讨论】:

【参考方案2】:

您可以通过更改 QuestionSerializer 以另一种方式尝试:

class QuestionSerializer(serializers.ModelSerializer):
    answers = serializers.SerializerMethodField()

    class Meta:
        model = Question
        fields = ('id', 'answers', 'created_at', 'text', 'user_id',)

    def get_answers(self,obj):
        ans_set = AnswerSerializer(Answer.objects.filter(question=obj),many=True)
        return ans_set

【讨论】:

【参考方案3】:

我认为该服务的数据格式不正确......

"text":"gf or ed","answers":["text":"gf","votes":0,"id":null,"text":"ed","votes":0,"id":null],"user_id":"temp user id"

'Picture' 不存在,你不是从 android 发送的......而且 Django 默认将字段设置为'required',所以它应该会导致你的问题......

你有任何来自 python 的踪迹吗?尝试调试它。

【讨论】:

【参考方案4】:

您在这里缺少您的 views.py 代码,但我猜您正在使用 ListCreateAPIView 开箱即用。事实证明,django rest 框架不支持自动创建开箱即用的嵌套对象,因此您需要添加自己的代码来解决该功能。这里有很好的文档:

http://www.django-rest-framework.org/api-guide/serializers/#writable-nested-representations

【讨论】:

以上是关于发布到我的 Django API 时:errorcom.google.gson.JsonParseException: 无法解析 json的主要内容,如果未能解决你的问题,请参考以下文章

为啥每当我尝试将图像添加到我的 django 项目时都会出错?

(Django)当我尝试将夹具文件加载到我的数据库中时,我不断收到字段冲突错误

来自 ALAssetRepresentation 的 NSData 在发送到我的 Django 服务器时总是有错误的方向

Django:从 API 加载数据

Nginx 和 Django - JWT 问题

没有存储的 Python Django Rest Post API