Django使用html按钮下载静态文件

时间:2018-12-15 12:52:35

标签: django

我正在用Django创建一个网站,用户可以在该网站上从不同的网站收集数据,进行审查,将其保存到数据库中,然后将所有数据下载为文件(txt或csv)。我有一个问题,我无法创建指向用户可以下载的特定静态文件的href链接({% static 'files/filename' %})。

当我尝试将href属性添加到链接并单击它时,出现此错误,而不是例如: <a id="download" href="/static/file/Shrek_reviews.txt" download=""></a>

我明白了:

<a id="download" href="/static/file/%22%20%2B%20btn_n%20%2B%20%22_reviews.txt" download=""></a>

有人可以告诉我如何将文件名解析为{% static 'file/file_name' %}以便其正常工作吗?

下面是我的视图函数和ajax函数,它们创建href属性并下载文件。预先感谢您的帮助

ajax功能

 $('button').click(function(){
            var btn_t = $(this).text();
            var btn_n = $(this).attr('name');
            $.ajax({
              type: "POST",
              url: "{% url 'proces:films_data' %}",
              data: {
                csrfmiddlewaretoken: '{{ csrf_token }}',
                btn_text:btn_t,
                btn_name:btn_n,
              },
              success: function(data){
                if(btn_t == 'txt') {
                    $("#download").attr("href", "{% static 'file/" + btn_n + "_reviews.txt' %}");
                } else {
                    $("#download").attr("href", "{% static 'file/" + btn_n + "_reviews.csv' %}");
                }
                $('#download').trigger('click');
              }
            });
        });

查看功能

def films_data(request):
db_film_data = Films.objects.all()

if request.method == "POST":
    data = {}
    db_selected_film = Films.objects.get(title=request.POST['btn_name'])
    db_film_reviews = Reviews.objects.filter(film_id=db_selected_film).all()
    file_path = os.getcwd() + '/static/file/' + db_selected_film.title + "_reviews.txt"

    if request.POST['btn_text'] == 'txt':
        with open(file_path, 'w', encoding='utf-8') as file:
            file.write("Film title: " + db_selected_film.title + '\n\n')
            for rev in db_film_reviews:
                file.write("Review title: " + rev.title + "\n")
                file.write("Review Author: " + rev.author + "\n")
                file.write("Review:\n" + rev.review + "\n")
                file.write("This review was helpful for " + rev.helpful + " users\n\n")

    return JsonResponse(data)
return render(request, 'proces/films.html', {'films': db_film_data})

2 个答案:

答案 0 :(得分:0)

这可能行不通。 Django模板标签已在服务器上呈现,远远早于JS可以在浏览器上执行之前。无法在Django模板标签中包含JS变量。

您应该完全在JS中进行串联。

var static = "{{ STATIC_URL }}"
if(btn_t == 'txt') {
    $("#download").attr("href", "file/" + btn_n + "_reviews.txt");
} else {
    $("#download").attr("href", "file/" + btn_n + "_reviews.csv");
}

尽管更好的方法是完全避免将文件写入静态目录。而是在Ajax响应中返回文件内容,并允许在JS中下载。

答案 1 :(得分:0)

感谢您的回答,我设法通过从链接中删除下载属性并将其添加到JS函数中来解决此问题。我还更改了保存文件的方式,方法是给它指定一个静态文件名,然后单击html链接时更改下载文件的名称。

这是我的新JS脚本:

$('button').click(function(){
            var btn_t = $(this).text();
            var btn_n = $(this).attr('name');
            $.ajax({
              type: "POST",
              url: "{% url 'proces:films_data' %}",
              data: {
                csrfmiddlewaretoken: '{{ csrf_token }}',
                btn_text:btn_t,
                btn_name:btn_n,
              },
              success: function(data){
                if(btn_t == 'txt') {
                    $("#download").attr("href", "{% static 'file/film_reviews.txt' %}");
                    $('#download').attr('download', btn_n + "_reviews.txt");
                } else {
                    $("#download").attr("href", "{% static 'file/film_reviews.csv' %}");
                    $('#download').attr('download', btn_n + "film_reviews.csv");
                }
                document.getElementById("download").click()
              }
            });
        });

现在效果很好