14

私はこれに完全に困惑しており、信じられないほど愚かなことをしているに違いありません。Django プロジェクトにファイルを単純にアップロードしようとしています。問題は、フォーム データがサーバーに渡されていないこと (csrf トークンのみ) にあるようです。MacでDjango 1.5.1、python 2.7、virtualenvを実行しており、組み込みのDjango開発サーバーを使用しています。

私のHTMLフォームは次のとおりです。

{% load url from future %}

<form enctype="multipart/form-data" method="POST" action="{% url 'showreport' %}">
    {% csrf_token %}
    <label>Upload grade csv file: </label>
    <input type="hidden" id="testing" value="maybe" />
    <input type="file" id="grade_csv" />
    <input type="submit" value="Generate Report" />
</form>

私のモデル:

from django.db import models

class Document(models.Model):
file = models.FileField(upload_to='/media/', blank=True, null=True)

私のforms.py:

from django import forms
from .models import Document

class DocumentForm(forms.Form):
"""
to handle uploading grades csv file
"""
class Meta:
    models = Document

私のviews.py:

def report(request):
"""
Process the CSV file to remove inactive students
Manipulate to get right JSON format
Chart the results
"""
if request.method == 'POST':
    form = DocumentForm( request.POST, request.FILES )
    if form.is_valid():
        newfile = Document( file = request.FILES['file'] )
        newfile.save()

        classdata = {}
        studentdata = {}

        return render( request, 'report/showreport.html', { 'classdata': classdata, 'studentdata': studentdata } )
else:
    form = UploadFileForm()

return render( request, 'report/index.html', { 'form': form })

解決策を探すのに数時間を費やしましたが、何もうまくいかないようです。私は enctype を正しく設定しており(私は思う)、 formに入力タイプ 'submit' を使用しており、フォーム データをモデルにバインドしています(request.FILES は空なので関係ありません)。この Django newbie pageごとに、フォーム アクション (action='/report/showreport/') で直接 URL を使用してみましたが、違いはありませんでした。私が知る限り、フォーム送信アクションにバインドし、デフォルト アクションをオーバーライドするスクリプトは他にありません。

また、上記のコードは、フォームの入力 ID と一致するように request.FILES['grades_csv'] にする必要があることも認識していますが、request.FILES は空であるため、それはまだ問題ではありません。

デバッグしようとして、ビューの if request.method == "POST" の直前に pdb トレースを設定しました。コンソールを使用すると、request.POST に非表示の「テスト」入力が含まれておらず、request.FILES が空であることがわかります。これをブラウザで実行すると、フォームページに戻り、基本的にフォームが無効であると表示されます。私のpdbの結果は次のとおりです。

(Pdb) request.FILES
(Pdb) <MultiValueDict: {}>
(Pdb) request.POST['testing']
(Pdb) *** MultiValueDictKeyError: "Key 'testing' not found in <QueryDict: {u'csrfmiddlewaretoken': [u'0tGCChxa3Po619dCi114Sb9jmWRt82aj']}>"
(Pdb) request.POST
<QueryDict: {u'csrfmiddlewaretoken': [u'0tGCChxa3Po619dCi114Sb9jmWRt82aj']}>

フォームが有効かどうかを確認せずに、views.py の request.FILES にアクセスしようとすると、次のエラーが発生します。

"Key 'file' not found in <MultiValueDict: {}>"

私は困惑しており、これを機能させることができない理由についての助けに感謝しています-それは単純であるように思われます. pdbを使用してプロジェクトディレクトリ内のファイルを手動で作成して書き込むことができるので、パーミッションが問題だとは思いません...問題はフォームにありますか?

4

4 に答える 4

22

enctypeプロパティをformタグに追加したことを確認してください。

公式ドキュメントの例: <form enctype="multipart/form-data" method="post" action="/foo/">

于 2015-12-28T17:40:12.267 に答える
2

私もこの問題を抱えていて、しばらくそれについて困惑していました。私のエラーは同じで、inputフィールドに必要なフィールドがありませんでした。

実際に必要なフィールドが何であるかを確認するには、この場合は非常に良い方法です:

from base.forms import DocumentForm ## or put whatever the name is of the app, which is unspecified in the question
print DocumentForm()

これにより、このオブジェクトが必要とするすべてのタグを含む、必要な html が出力されます。初めて見逃した非常にきちんとした機能ですが、ドキュメントで概説されています。

于 2014-03-17T22:55:05.937 に答える