【问题标题】:How to implement js to django to run 3 functions?如何实现js到django运行3个功能?
【发布时间】:2021-11-17 18:32:48
【问题描述】:

我发现这个question 可以为我工作,但我不知道javascript。我想运行 3 个函数,就像您在我的 views.py 中看到的那样,但我无法这样做,因为我使用 (forms.Form) 上传的一个文档来运行 3 个函数。你能帮我在我的 django 网站上实现这个 js 代码吗?

这是forms.py

class DocumentForm(forms.Form):
    docfile = forms.FileField(label='Select a file')

这是views.py

def save_exls(request):
    if request.method == 'POST':
        form = DocumentForm(request.POST, request.FILES)
        if form.is_valid():
            newdoc = Document(docfile=request.FILES['docfile'])
            newdoc.save()
            return redirect('html_exls')
    else:
        form = DocumentForm()
    documents = Document.objects.all()
    context = {'documents': documents, 'form': form,}
    return render(request, 'list.html', context)


def pandas_exls(request):
    if request.method == "POST":
        form = DocumentForm(request.POST, request.FILES)
        if form.is_valid():
            output = io.BytesIO()
            newdoc = request.FILES['docfile']
            dfs = pd.read_excel(newdoc, sheet_name=None, index_col=[0])
            writer = pd.ExcelWriter(output)
            for name, df in dfs.items():
                #pandas stuff
                done.to_excel(writer, sheet_name=name)
            output.seek(0)
            response = HttpResponse(
                output, content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
            response['Content-Disposition'] = 'attachment; filename=%s' % filename
            return response
    else:
        form = DocumentForm()
    return render(request, 'list.html', {'form': form})


def html_exls(request):
    if request.method == "POST":
        form = DocumentForm(request.POST, request.FILES)
        if form.is_valid():
            output = io.BytesIO()
            newdoc = request.FILES['docfile']
            dfs = pd.read_excel(newdoc, sheet_name=None, index_col=[0])
            writer = pd.ExcelWriter(output)
            for name, df in dfs.items():
                #pandas stuff for html 
                done.to_excel(writer, sheet_name=name)

            html = done.to_html()
            print(html)
            output.seek(0)
            response = HttpResponse(
             output, content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
            response['Content-Disposition'] = 'attachment; filename=%s' % filename
            return response
    else:
        form = DocumentForm()
    return render(request, 'list.html', {'form': form})

这是html文件,list.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Django site</title>
    </head>

    <body>

        <!-- Upload form. Note enctype attribute! -->
        <form action="{% url "pandas_exls" %}" method="post" enctype="multipart/form-data">
            {% csrf_token %}
            <p>{{ form.non_field_errors }}</p>

            <p>{{ form.docfile.label_tag }} {{ form.docfile.help_text }}</p>

            <p>
                {{ form.docfile.errors }}
                {{ form.docfile }}
            </p>

            <p><input type="submit" value="Upload"/></p>
        </form>
        <br/>
            {{html|safe}}
        

    </body>
</html>

提前致谢!

编辑

查看 cmets 以了解此编辑。这是我之前尝试过的,将所有内容放在一个函数中,但它不起作用。

def upload_file(request):
    if request.method == "POST":
        form = DocumentForm(request.POST, request.FILES)
        if form.is_valid():
            output = io.BytesIO()

            newdoc = request.FILES['docfile']
            #newdoc.save()  * if I include this, I got an error, see below

            dfs = pd.read_excel(newdoc, sheet_name=None, index_col=[0])
            writer = pd.ExcelWriter(output)
            for name, df in dfs.items():
                df.columns = df.columns.str.split('_', expand=True)
                new_data = df.stack(0)
                #rest of pandas computation everyting until done
                done.to_excel(writer, sheet_name=name)

            html = done.to_html()
            writer.save()
            output.seek(0)
            # return render(request, 'list.html', {'table': html}) **can't render html and it will not be showed
            filename = f"calculated_{newdoc.name}"
            response = HttpResponse(
                output, content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
            response['Content-Disposition'] = 'attachment; filename=%s' % filename
            return response
    else:
        form = DocumentForm()
    return render(request, 'list.html', {'form': form})

'*' 我收到了这个错误,AttributeError at /uploadfile/ 'InMemoryUploadedFile' object has no attribute 'save'

'**'不能有两个returns

【问题讨论】:

  • 嘿,从您的代码示例中,我看到您正在调用函数pndas_exls。根据我从您的问题中了解到的情况,您想运行 save_exls 和 html_exls 但所有这些函数都会返回给用户一些不同的东西。你能详细说明应该发生什么吗?给用户
  • @Paulo 用户需要上传 (excel) 文件。之后,我需要将该文档保存在服务器上(这对用户来说并不重要),然后 pandas_exls 会进行一些 pandas 计算并为用户弹出下载窗口......另外还会在 html 页面中显示一些表格。因为我不能用一个功能来完成我得到的三个功能: 1 - 只需要保存文件; 2 - 需要进行pandas计算和下载文件,并且; 3 - 需要再次计算并在html页面中显示表格(我知道它会进行两次pandas计算但不知道其他方式)。
  • 那么我认为你没有必要为此设置 3 个端点。当您使用相同的文件时。只发送一次会更有效率。此外,我相信熊猫计算很快(几毫秒?)。如果是这样,我会做的是,在同一端点做所有 3 件事,1)首先保存文件,2)用 panda 执行计算并将其保存为另一个文件。 3)返回panda计算的数据表,并在之前生成的文件中添加链接,方便用户下载。最后只需要一个端点来执行所有 3 项任务。
  • 这对你有意义吗?它们是我没有预料到的一些陷阱吗?
  • 我试过这样做,我编辑了我的答案。我有一个错误,也许你可以解决它们。注意:熊猫时间取决于,一些更大的文件甚至可能需要 10 秒。查看已编辑的部分,您将在一个功能中看到所有内容。

标签: javascript python html django django-views


【解决方案1】:

forms.py

from django import forms    
class DocumentForm(forms.Form):
    docfile = forms.FileField(label='Select a file')

views.py

from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import UploadFileForm
from calculation import handle_uploaded_file


def upload_file(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            html_to_show = handle_uploaded_file(request.FILES['file'])
            return HttpResponse(html_to_show)
    else:
        form = DocumentForm()
    return render(request, 'upload.html', {'form': form})

计算.py

def do_calculation(fname):
    df = pd.read_excel(fname)
    #Perform df operations here
    return df.to_html()

def handle_uploaded_file(f):
    fname = 'some/file/name.xlsx'
    with open(fname, 'wb+') as destination:
        for chunk in f.chunks():
            destination.write(chunk)
    return do_calculation(fname)

编辑(如何提供上传的文件)

我们将呈现另一个视图,该视图期望来自响应 file_url 和 html_table_to_show 的 2 个变量

views.py

from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import UploadFileForm
from calculation import handle_uploaded_file


def upload_file(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            html_to_show, file_url = handle_uploaded_file(request.FILES['file'])
            return render(request, '/viewToRender.html', {
        'uploaded_file_url': file_url, 'table_view': html_to_show 
    })
    else:
        form = DocumentForm()
    return render(request, 'upload.html', {'form': form})

计算.py

def do_calculation(fname):
    df = pd.read_excel(fname)
    #Perform df operations here
    df.to_excel(fname)
    return df.to_html()

def handle_uploaded_file(f):
    fname = 'some/file/name.xlsx'
    with open(fname, 'wb+') as destination:
        for chunk in f.chunks():
            destination.write(chunk)
    return do_calculation(fname), fname

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-07-28
  • 2019-11-20
  • 2021-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-25
相关资源
最近更新 更多