Django:在按钮点击时动态生成数据作为附件

3 投票
2 回答
3468 浏览
提问于 2025-04-17 04:07

问题概述:

我正在创建一个基于Django的客户端,目的是从一个网络服务获取数据。这个项目的目标是根据用户在表单中选择的值,从网络服务返回数据。当用户提交表单时,会生成一个查询字符串,发送到网络服务,然后页面数据以字符串的形式返回。目前,这些数据会在浏览器中显示给用户。我想提供一个功能,让用户可以点击一个按钮下载这些数据。

问题:

当用户在浏览器中点击一个按钮下载数据时,我该如何将数据返回给他们?我怎么才能提供同一数据的不同格式选项(比如 application/json 或 text/csv)?

当前(不工作的)实现:

我正在尝试,但没有成功,做以下事情:

views.py

返回一个渲染模板的对象。我把表单和各种形式的数据传递给模板。

def view(request):
    #Do stuff, get data as string

    #Get data into needed formats (see utils.py)
    jsonData  = jsonToJsonFile(dataString, fileName)

    return render_to_response('template.html', {'someForm'    : aForm,
                                                'regularData' : stringData,
                                                'jsonData'    : jsonData...})

utils.py

包含一些函数,用来处理字符串形式的数据并返回响应对象。这部分我不太确定自己做得对不对。我在视图中调用这些函数,把 jsonData(和 csvData)从原始数据字符串转换成正确的格式。

def jsonToJsonFile(dataString, fileName):

    #Get the data as json
    theData = json.dumps(dataString)

    #Prepare to return a json file
    response = HttpResponse(theData, mimetype = 'application/json')
    response['Content-Disposition'] = 'attachment; filename=' + str(fileName) + '.json'

    #return the response
    return response 

template.html

我目前把响应传递到模板中。在这里我真的很迷茫,还没有找到好的解决方案。我想我需要用JavaScript来在按钮被点击时把变量(jsonData和csvData)返回给用户。我尝试过使用锚点类的onclick动作,然后用JavaScript返回Django的响应变量,但这真的没有效果。

<li class = 'button'>
    <a  href = "#dataButtons" onclick = "javaScript:alert('test');"> 
    TEST
    </a>
</li>
<li class = 'button'>
    <a  href = "#dataButtons"  onclick = "javaScript: var a = '{{ jsonData }}'; return a;"> 
    JSON
    </a>
</li>

我把测试部分放在那里,嗯,测试一下警告是否有效。结果是有效的。但是,当我点击获取json数据的按钮时,什么也没有发生。

我是不是完全走错方向了?还是说我遗漏了什么小细节?

2 个回答

2

我觉得你需要修改一下你的JavaScript代码,这样才能开始下载文件。你可以看看这个问题和答案:用JavaScript开始文件下载

5

解决方案:

在仔细研究这个问题并和同事讨论后,我发现我的问题在于试图把响应对象传递给JavaScript。对这个问题感兴趣的人,我通过稍微调整数据的传递方式解决了这个问题。

views.py

在我的views.py文件中,我在主视图里添加了几行代码,这样就可以把两个额外视图(一个用于csv,一个用于json)的变量设置为包含数据的响应对象。当用户点击相应的按钮时,这两个额外的视图就会被调用,返回http响应并提示用户下载。

#MAIN VIEW FUNCTION
def view(request):
    #Do stuff, get data as string

    #Get data into needed formats 
    jsonData  = jsonToJsonFile(dataString, fileName)

    #Set values to external view ****NEW PART****
    returnJSON.jsonData = jsonData

    #Render main template
    return render_to_response('mainTemplate.html', {'someForm'    : aForm,
                                                    'regularData' : dataString})

#SECONDARY VIEW TO RETURN JSON DATA TO USER ****NEW PART****
def returnJSON(request):
    #Simply return the response
    return returnJSON.jsonData

template.html

然后,当用户点击按钮时,链接会通过网址指向那个次级的Django视图,这样用户就可以看到下载选项。

<li class = 'button'>
    <a  href = "{% url client.views.returnJSON %}"> 
        JSON
    </a>
</li>

urls.py

最后,我只是把我的网址模式指向了这个视图。

urlpatterns = patterns('',
    (r'^somesite/$', views.view),
    (r'^somesite/json$',  views.returnJSON),
)

到目前为止,这种方法对我来说效果很好!如果有人有其他建议或者更好的方法,我非常乐意听取。

撰写回答