2017-02-07 68 views
10

Używam Dropzone.js, aby umożliwić przeciąganie i upuszczanie przesyłanie plików CSV za pośrednictwem strony internetowej Flask. Proces przesyłania działa świetnie. Zapisuję przesłany plik w określonym folderze i mogę następnie użyć df.to_html(), aby przekonwertować kod dataframe na HTML, który następnie przekazuję do mojego szablonu. Przechodzi do tego punktu w kodzie, ale nie renderuje szablonu i nie są zgłaszane żadne błędy. Moje pytanie brzmi: dlaczego Dropzone.js uniemożliwia wykonanie renderowania?Dropzone.js uniemożliwia Flask z renderowania szablonu

Próbowałem również po prostu zwrócić kod HTML ze stołu i nie używając render_template, ale to również nie działa.

startowych .py

import os 
from flask import Flask, render_template, request 
import pandas as pd 

app = Flask(__name__) 

# get the current folder 
APP_ROOT = os.path.dirname(os.path.abspath(__file__)) 

@app.route('/') 
def index(): 
    return render_template('upload1.html') 


@app.route('/upload', methods=['POST']) 
def upload(): 

    # set the target save path 
    target = os.path.join(APP_ROOT, 'uploads/') 

    # loop over files since we allow multiple files 
    for file in request.files.getlist("file"): 

     # get the filename 
     filename = file.filename 

     # combine filename and path 
     destination = "/".join([target, filename]) 

     # save the file 
     file.save(destination) 

     #upload the file 
     df = pd.read_csv(destination) 
     table += df.to_html() 

    return render_template('complete.html', table=table) 


if __name__ == '__main__': 
    app.run(port=4555, debug=True) 

upload1.html

<!DOCTYPE html> 

<meta charset="utf-8"> 

<script src="https://rawgit.com/enyo/dropzone/master/dist/dropzone.js"></script> 
<link rel="stylesheet" href="https://rawgit.com/enyo/dropzone/master/dist/dropzone.css"> 


<table width="500"> 
    <tr> 
     <td> 
      <form action="{{ url_for('upload') }}", method="POST" class="dropzone"></form> 
     </td> 
    </tr> 
</table> 

EDIT

Oto przykładowe dane csv ja przesłaniem:

Person,Count 
A,10 
B,12 
C,13 

Complete.html

<html> 

<body> 

{{table | safe }} 

</body> 
</html> 
+0

Twoja instrukcja return jest wewnątrz pętli for, tylko pierwsza iteracja pętli będzie biegać przed powrotem. Jak myślisz, dlaczego Dropzone.js coś robi? JavaScript działa na kliencie, Flask i Jinja działają na serwerze osobno. – davidism

+0

@davidism. Masz rację, jeśli jesteś w "pętli for". Naprawiłem to przez backdenting, ale nadal mam ten sam problem. Nie wiem na pewno, że to "dropzone.js", ale uważam, że jest to spowodowane procesem eliminacji. Jeśli skopiuję tę trasę i załaduję 'html' z odczytu pliku' csv' z mojego dysku twardego, to działa dobrze. – user2242044

+0

jaka jest zawartość "complete.html"? – HassenPy

Odpowiedz

3

Dropzone.js używać AJAX aby umieścić dane, to dlaczego nie odda kontrola do funkcji widoku.

Istnieją dwie metody przekierowania (lub renderowania szablonu) po całkowitym przesłaniu wszystkich plików.

  • Możesz dodać przycisk do przekierowania.

    <a href="{{ url_for('upload') }}">Upload Complete</a>

  • Możesz dodać detektor zdarzeń do automatycznego przekierowania stronie (użyć jQuery).

    <script> 
    Dropzone.autoDiscover = false; 
    
    $(function() { 
        var myDropzone = new Dropzone("#my-dropzone"); 
        myDropzone.on("queuecomplete", function(file) { 
        // Called when all files in the queue finish uploading. 
        window.location = "{{ url_for('upload') }}"; 
        }); 
    }) 
    </script> 
    

w świetle funkcji, dodać oświadczenie if, by sprawdzić, czy metoda HTTP był POST:

import os 
from flask import Flask, render_template, request 

app = Flask(__name__) 
app.config['UPLOADED_PATH'] = os.getcwd() + '/upload' 

@app.route('/') 
def index(): 
    # render upload page 
    return render_template('index.html') 


@app.route('/upload', methods=['GET', 'POST']) 
def upload(): 
    if request.method == 'POST': 
     for f in request.files.getlist('file'): 
      f.save(os.path.join(app.config['UPLOADED_PATH'], f.filename)) 
    return render_template('your template to render') 
5

Kod robi pracy. Twój szablon zostanie wyrenderowany i zwrócony.

Dropzone prześle pliki, które przeciągniesz i upuścisz do przeglądarki "w tle". Spowoduje to odebranie odpowiedzi z serwera i zamknięcie strony tak, jak jest. Używa odpowiedzi z serwera, aby dowiedzieć się, czy przesyłanie zakończyło się powodzeniem.

Aby zobaczyć to w akcji:

  • Przejdź do strony
  • otworzyć swoje ulubione narzędzia dev przeglądarka; (W Firefox Ctrl + Shift + K)
  • Wybierz kartę sieciową
  • przeciągnij csv do okienka DropZone i pamiętać, że wniosek pokazuje w tabeli sieciowego narzędzia dev

Oto zrzut ekranu z mojej przeglądarki. Skopiowałem twój kod tak, jak pochodzi z twojego pytania.

Screen shot of code working

Aby rzeczywiście zobaczyć wygenerowana complete.html trzeba będzie dodać kolejny punkt końcowy kolby i mają sposób nawigacji do tego.

Na przykład: w upload1.html dodają:

<a href="{{ url_for('upload_complete') }}">Click here when you have finished uploading</a> 

w init.py zmian i dodać:

def upload(): 

    ... 

     # you do not need to read_csv in upload() 
     #upload the file 
     #df = pd.read_csv(destination) 
     #table += df.to_html() 

    return "OK" 
    # simply returning HTTP 200 is enough for dropzone to treat it as successful 
    # return render_template('complete.html', table=table) 

# add the new upload_complete endpoint 
# this is for example only, it is not suitable for production use 
@app.route('/upload-complete') 
def upload_complete(): 
    target = os.path.join(APP_ROOT, 'uploads/') 
    table="" 
    for file_name in os.listdir(target): 
     df = pd.read_csv(file_name) 
     table += df.to_html() 
    return render_template('complete.html', table=table) 
+0

Dzięki, świetna odpowiedź. W końcu dodałem link. Nie ma możliwości automatycznego renderowania? – user2242044