在Django中,是否可能返回一个包含文本和JSON对象的HttpResponse?

16
在我的视图函数中,我想返回一个JSON对象(data1)和一些文本/HTML(表单)。这可能吗?
下面是我的views.py的部分代码:
if request.is_ajax() and request.method == 'POST':
...
    if form.is_valid():
        answer = form.cleaned_data['answer'] # Answer extracted from form is also a string
        a1 = ques1.correct_answer
                    if a1 == answer:
            test1 = question_list.get(id=nextid)
            form = AnswerForm(test1)
            ques1 = question_list.filter(id=nextid)                     # Filter next question as <qs>
            data1 = serializers.serialize("json",ques1)                 # Json-ize
    # ********EDITED HERE **********        
            variables1 = Context({
                'form' : form,
                'q1'   : data1,
            })  
            #response = HttpResponse()
            #response['data1'] = response.write(data1)
            #response['form'] = response.write(form) 
            if nextid <= qsnlen:
                return HttpResponse(variables1, mimetype="application/json")
                #return HttpResponse(response)
            else:
...

我想同时返回表单HTML和ques1 JSON对象,我该如何做?谢谢提前。

3个回答

13

使用JsonResponse

from django.http import JsonResponse
response_data = {put your data into a dict}
return JsonResponse(response_data, status=201)

11

只需要将两个数据放入一个JSON容器中,一个键用于表单数据,另一个键用于HTML的渲染字符串。在浏览器中,您可以轻松地获取这两个键并进行处理。

在您的视图中:

form_json_data = get_form_json_data()
rendered_html = get_the_html()
return HttpResponse(json.dumps({
        "formdata": form_json, 
        "html": rendered_html}),
    content_type="application/json")

在JavaScript中:

$.post(foo, postdata, function(data){
    var formdata = data.formdata
    var html = data.html;
    $(".html-target").replaceWith(html);
    do_whatever(formdata);
})

我尝试了你建议的方法,但问题是上面的'ques1'是一个queryset,而json.dumps抱怨无法序列化这个queryset。事实上,即使你只尝试序列化对象('test1'),它也会抱怨。此外,在我的上述代码中,我想要发送回两件东西,即表单和问题对象。 - Harshil Parikh
2
嗯,没错,你不能将Python对象进行JSON序列化。你不能直接发送“问题对象”,你只能发送对象属性的JSON字典。Django有一个内置的序列化辅助工具,可以处理查询集。 - AdamKG
1
导入HttpResponse:from django.http import HttpResponse - Zohab Ali

0

如果需要一次性返回JSON,您需要将JSON作为纯文本发送在模板响应(HTML)的上下文中。

如果您需要以单独的JSON对象形式发送JSON,并具有其自己的MIME类型,则需要编写两个视图:一个将JSON作为 application / json 发送回,另一个将表单(HTML)发送回。

编辑:

您没有返回JSON对象,但您正在转换具有两个不同类型的两个项目的字典。正如我在评论中所解释的那样,在一个请求/响应循环中,您只能返回一个响应,该响应具有基于内容和您希望浏览器处理的方式的特定MIME类型。大多数情况下,内容类型为'text/html'

在您的场景中,如果您想同时返回HTML(即您的表单)和JSON响应(即字符串),则需返回HTML。

如果要将JSON作为JSON对象返回给jQuery,则需要检测请求类型。在前端(模板)中,您将启动两个请求-一个来自浏览器,它将返回表单。另一个来自jQuery,它将返回适当的JSON对象。

以下是可能的方法:

  def foo(request):
     if request.is_ajax():
        ctx = dict()
        ctx['hello'] = 'world'
        return HttpResponse(json.dumps(ctx),content_type='application/json')
     else:
        return HttpResponse('hello world')

只是为了100%清楚 - 我正在发送一个带有表单数据的HttpRequest POST请求(通过ajax),因此我只能将其路由到一个视图函数。在我的情况下,当用户提交问题的答案时,我想接收该数据,对其进行处理,然后发送回另一个问题json对象和一个新的输入表单。 - Harshil Parikh
您可以返回一个响应,其中包含多个对象。这些对象只能是一种_mime类型_ - 因此您可以在响应中发送多个项目;但是您不能在一个响应中组合两种mime类型。在您的示例中,您将mimetype设置为application/json。技术上,您可以发送任何您想要的内容,并将mimetype设置为任何内容,但这不会在客户端端点上实现您想要的效果。要发送表单的HTML和JSON对象,请将JSON对象添加到响应的上下文中。 - Burhan Khalid
请检查上面编辑过的代码。我将表单和JSON对象都添加到了上下文中,并将其发送回去。这是你想要的吗?JSON对象在客户端上能够正确读取吗(我正在使用jQuery)?我认为在客户端上阅读这个会有点困难。我没有使用RequestContext,因为返回的变量还有很多我不需要的。感谢您的帮助。 - Harshil Parikh
你不能有两个返回语句;只有第一个会生效。在一个请求中,你只能返回一个响应。你不能在一个请求/响应周期中分叉两个具有不同 MIME 类型的响应。 - Burhan Khalid
抱歉,我本意是要注释掉第二个返回语句。虽然现在我可以在响应中获取表单和JSON对象,但我仍在尝试通过jQuery适当地解包它们。 - Harshil Parikh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接