【问题标题】:Prompt File Download after upload in django admin在 django admin 中上传后提示文件下载
【发布时间】:2016-12-19 04:13:43
【问题描述】:

我有一个 django 管理页面,用户在其中上传文件,数据被读取内存中,而没有实际存储文件。

根据内容,在磁盘上生成一个新文件。这一切都发生在save_model被调用之前的clean方法中。下面是生成输出文件的方法

def clean(self):
    obj = Parser()
    cleaned_data = super(MyMethodAdminForm, self).clean()
    input_data = self.request.FILES['file_name'].read().split('\n')
    base_file = settings.MEDIA_ROOT + "/uploads/" + cleaned_data.get('file_name').name

    # This is the output file, which needs to be downloaded
    output_filename = base_file.replace('.csv', '_output.csv')
    output_list = []

    # Read the file and prepare the output data
    # on the basis of the input data
    for line in input_data:
        data = line.split(",")
        if len(data) > 1:
            dt = obj.get_data()
            current_list = [data[0], data[1]]
        else:
            dt = obj.get_data()
            current_list = [data[0]]
        current_list.append(str(dt))
        output_list.append(current_list)

    # Prepare the file on the basis of the output data
    with open(output_filename, 'a') as outcsv:
        # configure writer to write standard csv file
        writer = csv.writer(outcsv, delimiter=',', quotechar=' ', quoting=csv.QUOTE_MINIMAL, lineterminator='\n')
        for item in output_list:
            if len(item) > 2:
                # Write item to outcsv
                writer.writerow([item[0], item[1], item[2]])
            else:
                writer.writerow([item[0], item[1]])
    return cleaned_data

现在,我的问题是我必须允许下载此文件,但由于上传域是通过负载平衡器处理的,我无法真正提供链接(老实说,这也不是首选方式)。是有什么办法可以强制提示下载文件?

我从以下两个问题中得到了一些提示,但后来不明白我需要把这些change header thing

编辑

经过更多调试后,我尝试按照线程Redirect on admin Save 中的建议更新response_change

    class MyMethodAdmin(admin.ModelAdmin):
        form = MyMethodAdminForm

        def response_change(self, request, obj):
            import ipdb;
            ipdb.set_trace()
            # response = HttpResponse(content_type='text/csv')
            # response['Content-Disposition'] = 'attachment; filename="%s"' % form.cleaned_data['output_file_path'] (somehow access the file-path, its incorrect ryt now, i know

            super(MyMethodAdmin, self).response_change(request, obj)

但是连 pdb 都没有被调用....所以还没有帮助!! :(

完整的课程:

class MyMethodAdminForm(forms.ModelForm):
    class Meta(object):
        model = MyMethod
        fields = ["file_name"]

    def clean(self):
        obj = Parser()
        cleaned_data = super(MyMethodAdminForm, self).clean()
        input_data = self.request.FILES['file_name'].read().split('\n')
        base_file = settings.MEDIA_ROOT + "/uploads/" + cleaned_data.get('file_name').name
        output_filename = base_file.replace('.csv', '_output.csv')
        output_list = []

        # Read the file and prepare the output data
        # on the basis of the input data
        for line in input_data:
            data = line.split(",")
            if len(data) > 1:
                dt = obj.get_data()
                current_list = [data[0], data[1]]
            else:
                dt = obj.get_data()
                current_list = [data[0]]
            current_list.append(str(dt))
            output_list.append(current_list)

        # Prepare the file on the basis of the output data
        with open(output_filename, 'a') as outcsv:
            # configure writer to write standard csv file
            writer = csv.writer(outcsv, delimiter=',', quotechar=' ', quoting=csv.QUOTE_MINIMAL, lineterminator='\n')
            for item in output_list:
                if len(item) > 2:
                    # Write item to outcsv
                    writer.writerow([item[0], item[1], item[2]])
                else:
                    writer.writerow([item[0], item[1]])
        return cleaned_data

【问题讨论】:

  • 你的 response_change 缩进是故意的吗?
  • 不正确复制粘贴的缺点...已更正

标签: python django file download django-admin


【解决方案1】:

无论您准备在何处向用户发送响应:

response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="%s"' % filename
writer = csv.writer(response)
# now write to writer however you want to output your CSV

根据调用视图的位置,您可能需要覆盖多种方法。原因是 django 支持不同类型的管理操作,包括changeadddeletewhich you can read about here。我不确定您使用的是哪一种,因此您可能必须同时尝试两种方法。作为第一步,我会尝试覆盖 response_changeresponse_add 方法:

class MyMethodAdmin(admin.ModelAdmin):
    form = MyMethodAdminForm

    def return_csv(self):
        response = HttpResponse(content_type='text/csv')
        response['Content-Disposition'] = 'attachment; filename="%s"' % filename
        writer = csv.writer(response)
        writer.writerow(['Django','Admin'])
        return response

    def response_change(self, request, obj):
        return self.return_csv()

    def response_add(self, request, obj):
        return self.return_csv()

【讨论】:

  • "... 无论您准备在哪里向用户发送响应 ...." 这就是我不知道的重点...哪种方法是关键这?请看我的更新
  • 发布你的完整课程clean
  • 它只包含我添加的clean 方法
  • 是的,但我需要整个类,包括类名和继承来帮忙。
猜你喜欢
  • 2020-09-17
  • 1970-01-01
  • 2011-09-16
  • 2017-05-22
  • 1970-01-01
  • 2018-10-13
  • 2017-03-16
  • 2012-05-20
  • 2020-10-18
相关资源
最近更新 更多