问题 是否可以使用text和json对象返回django中的HttpResponse?


在我的视图函数中,我想返回一个json对象(data1)和一些text / html(form)。这可能吗?

这是我的一部分 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对象。我怎样才能做到这一点?提前致谢。


3834
2018-01-29 07:05


起源



答案:


只需将两个数据放在一个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")

在js中:

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

9
2018-01-29 14:02



我尝试了你的建议,但问题是上面的'ques1'是一个查询集,并且json.dumps抱怨无法序列化这个查询集。事实上,即使您尝试仅序列化对象('test1'),它也会抱怨。另外,在我上面的代码中,我要发回的两件事是表单和问题对象。 - Harshil Parikh
好吧,你不能JSON序列化Python对象。你不能发送'问题对象'本身;你只能发送对象属性的JSON字典。 Django有一个 内置的序列化助手 可以处理查询集。 - AdamKG
要导入HttpResponse: 来自django.http导入HttpResponse - Zohab Ali


答案:


只需将两个数据放在一个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")

在js中:

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

9
2018-01-29 14:02



我尝试了你的建议,但问题是上面的'ques1'是一个查询集,并且json.dumps抱怨无法序列化这个查询集。事实上,即使您尝试仅序列化对象('test1'),它也会抱怨。另外,在我上面的代码中,我要发回的两件事是表单和问题对象。 - Harshil Parikh
好吧,你不能JSON序列化Python对象。你不能发送'问题对象'本身;你只能发送对象属性的JSON字典。 Django有一个 内置的序列化助手 可以处理查询集。 - AdamKG
要导入HttpResponse: 来自django.http导入HttpResponse - Zohab Ali


使用 JsonResponse

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

4
2017-11-19 04:19





用一个回复做到这一点;您需要在模板响应(HTML)的上下文中将JSON作为纯文本发送。

如果您需要将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')

0
2018-01-29 07:20



只是100%清除 - 我发送一个带表单数据的HttpRequest POST请求(通过ajax),所以我只能将它路由到一个视图函数。在我的场景中,当用户提交问题的答案时,我想接收该数据,用它做一些事情,然后发回另一个问题json对象和一个新的输入表单。 - Harshil Parikh
您可以返回一个响应,在上下文中包含多个对象。这可能只有一个 哑剧型  - 这样你就可以在回复中发送多个项目;但是你 不能 在一个响应中组合两个mime类型。在您的示例中,您将mimetype设置为 application/json。你可以在技术上发送任何你想要的东西,并把mimetype作为任何东西,但这不会在客户端做你想要的。要发送表单和JSON对象的HTML,请将JSON对象添加到响应的上下文中。 - Burhan Khalid
请检查上面编辑的代码。我将表单和json对象添加到上下文中,然后我将其发回。你是这个意思吗? json对象是否会在客户端正确读取(我正在使用jquery)?我认为,在客户端阅读这将是一个噩梦。我没有使用RequestContext,因为还有很多我不需要返回的变量。谢谢你的帮助。 - Harshil Parikh
你不能有两个return语句;只有第一个才有效。只有一个请求 - 您只能返回一个响应。在一个请求/响应周期中,您不能使用两种不同的mime类型分叉两个响应。 - Burhan Khalid
对不起,我打算将第二份退货声明注释掉。虽然我现在在响应中同时获得了form和json对象,但我仍然试图弄清楚如何通过jquery在客户端端适当地解包它。 - Harshil Parikh