首页 > 解决方案 > Django在重定向后下载文件

问题描述

您好,我试图弄清楚如何下载文件和重定向,这里有人建议我window.location.href用来模拟用户被重定向到的模板中的链接点击。起初,我很难找到一种将 url 从我的视图传递到我开始工作的模板的好方法,但是在尝试将两个 url 传递给模板时遇到了问题。我放弃了这个想法,决定只使用模板过滤器来返回我需要的 url,你可以在下面看到。

过滤器.py

@register.filter()
def pdf_download_url(value, arg):
    """
    Takes an attendance object and returns the url to download the PDF and Counseling PDF if available.

    :param value: Attendance object
    :return: A list with Url for PDF download and URL for Counseling PDF download if there is one
    """
    attendance_download_url = arg + reverse('employee-attendance-download', args=[value.employee.employee_id, value.id])

    try:
        counseling_id = value.counseling.id
        counseling_download_url = arg + reverse('employee-counseling-download', args=[value.employee.employee_id, counseling_id])
    except Counseling.DoesNotExist:
        counseling_download_url = ''

    return [attendance_download_url, counseling_download_url]

然后在我的模板中,我有以下代码。

account.html

{% if download == 'True' and attendance.last.downloaded == False %}
    window.onload = function(e){
        {% for url in attendance.last|pdf_download_url:request.get_host %}
            window.location.href = '{{ url }}'
        {% endfor %}
        }
{% endif %}

然后是我的看法。

@login_required
def account(request, employee_id, download=None):
    employee = Employee.objects.get(employee_id=employee_id)
    attendance = Attendance.objects.filter(employee=employee).order_by('id')
    counseling = Counseling.objects.filter(employee=employee)

    data = {
        'employee': employee,
        'attendance': attendance,
        'counseling': counseling,
        'download': download,
    }

    return render(request, 'employees/account.html', data)


@login_required
def attendance_download(request, employee_id, attendance_id):
    employee = Employee.objects.get(employee_id=employee_id)
    attendance = Attendance.objects.get(id=attendance_id)
    pretty_filename = f'{employee.first_name} {employee.last_name} Attendance Point.pdf'

    try:
        with open(attendance.document.path, 'rb') as f:
            response = HttpResponse(f, content_type='application/vnd.ms-excel')
            response['Content-Disposition'] = f'attachment;filename="{pretty_filename}"'

            attendance.downloaded = True

            return response
    except:
        messages.add_message(request, messages.ERROR, 'No File to Download')
        print('Exception')
        return redirect('employee-account', employee_id)


@login_required
def assign_attendance(request, employee_id):
    employee = Employee.objects.get(employee_id=employee_id)
    if request.method == 'GET':

        a_form = AssignAttendance()

        data = {
            'a_form': a_form,
            'employee': employee
        }

        return render(request, 'employees/assign_attendance.html', data)
    else:
        a_form = AssignAttendance(request.POST)

        if a_form.is_valid():
            employee_name = f'{employee.first_name} {employee.last_name}'
            incident_date = a_form.cleaned_data['incident_date'].strftime('%m-%d-%Y')
            reason = a_form.cleaned_data['reason']
            reported_by = f'{request.user.first_name} {request.user.last_name}'

            # This has been ordered to match the document
            history = {
                '0': 0,
                '6': 0,
                '7': 0,
                '2': 0,
                '4': 0,
                '5': 0,
                '3': 0,
            }

            exemption = a_form.cleaned_data['exemption']

            attendance_records = Attendance.objects.filter(employee=employee)

            # Goes through each of the past attendance points and adds +1 to the history ignoring '1'(Consecutive) and
            # treating '8'(Late Lunch) as '6'(< 15min)
            for attendance_record in attendance_records:
                if attendance_record.reason != '1':
                    if attendance_record.reason == '8':
                        history['6'] += 1
                    else:
                        history[attendance_record.reason] += 1

            counseling = counseling_required(employee, reason, exemption)

            document = create_attendance_document(employee_name, incident_date, reason, reported_by, history, exemption, counseling)
            a_form.save(employee, request, document, counseling)

            messages.add_message(request, messages.SUCCESS, 'Attendance Point Successfully Assigned')

            return redirect('employee-account', employee_id=employee_id, download='True')
        else:
            data = {
                'a_form': a_form,
                'employee': employee
            }

            return render(request, 'employees/assign_attendance.html', data)

问题是,一旦我通过 download == 'True' 重定向到我的帐户页面,该页面就会不断地无限重新加载,并且永远不会开始下载。起初我以为是因为 URL 永远不会改变所以它继续,所以我尝试在我的Attendance模型中添加一个 bool 标志设置为 false,然后在下载后切换到 True,但这似乎没有帮助。

编辑 Added the assign_attendance view.

标签: pythondjangodjango-viewsdjango-templates

解决方案


推荐阅读