web-dev-qa-db-fra.com

Requête vide.FILES avec les formulaires de téléchargement Django

Essayer d'utiliser un formulaire très simple pour télécharger un fichier dans une nouvelle instance de classe. Je m'attends à avoir les deux fichiers dans request.FILES mais c'est vide. Je suis sur le serveur de développement fourni.

Été coincé ici et passé en revue toutes les questions connexes.

wayfinder_map.media_file = request.FILES['media_file'] 

génère

MultiValueDictKeyError: "La clé 'media_file' est introuvable dans MultiValueDict: {}>"

modèle

class WayfinderMap(models.Model):
    """ Way-finding Map Config"""


    media_file = models.FileField(upload_to="maps", null=True, blank=True) 
    wall_file = models.FileField(upload_to="maps_data", null=True, blank=True) 

vue

@login_required
def create_map(request, form_class=WayfinderMapForm, template_name="wayfinder/map/create.html"):
wayfinder_map_form = form_class(request.user, request.POST or None, request.FILES)

    if wayfinder_map_form.is_valid():
        wayfinder_map = wayfinder_map_form.save(commit=False)
        wayfinder_map.media_file = request.FILES['media_file']
        wayfinder_map.data_file = request.FILES['data_file']
        wayfinder_map.creator = request.user
        wayfinder_map.save()
    return HttpResponseRedirect(wayfinder_map.get_absolute_url())

return render_to_response(template_name, {
    "wayfinder_map_form": wayfinder_map_form,
}, context_instance=RequestContext(request))

modèle

<form enctype="multipart/form-data" class="uniForm" id="wayfinder_map_form" method="POST" action="">
        <fieldset class="inlineLabels">
            {{ wayfinder_map_form|as_uni_form }}
            <div class="form_block">
                <input type="hidden" name="action" value="create" />
                <input type="submit" value="{% trans 'create' %}"/>
            </div>
        </fieldset>
    </form>
40
philgo20

Il semble que request.FILES ne soit pas nécessaire dans ce cas (bonne chose car il est vide ...)

J'ai modifié cette ligne 

wayfinder_map.media_file = request.FILES['media_file'] 

pour 

wayfinder_map.media_file = wayfinder_map_form.cleaned_data['media_file'] 

et il fonctionne. Je ne sais pas quelle est la bonne façon de faire si ... -

3
philgo20

vieille question, mais quelqu'un pourrait encore trouver cela utile.

Pour que vos fichiers <input type=file> soient chargés et affichés dans request.FILES, votre formulaire DOIT contenir enctype="multipart/form-data", par exemple:

<form action="" method="post" enctype="multipart/form-data">{% csrf_token %}
{{ form.as_p }}
<button type="submit">{% trans 'Submit' %}</button>
</form>

sinon, vos fichiers ne seront pas téléchargés et votre request.FILES sera vide.

BTWC'est une solution courante à une erreur commune. Néanmoins, je me suis toujours retrouvé dans une situation avec des FICHIERS vides (et le fichier dans le POST) alors que tout semblait aller pour le mieux. J'ai l'impression que c'était une limite de taille, mais je ne voulais pas passer plus de temps à déboguer, et je viens d'utiliser request.raw_post_data. Si jamais quelqu'un tombe sur cette question s'il vous plaît ajoutez un commentaire (y compris la version précise de Django!) Et je vais essayer de déboguer plus profondément.

165
Stefano

J'ai trouvé que si vous mettez le formulaire dans un bloc de contenu, il semble fonctionner 

    {% block content %}
<form enctype="multipart/form-data" class="uniForm" id="wayfinder_map_form" method="POST" action="">
        <fieldset class="inlineLabels">
            {{ wayfinder_map_form|as_uni_form }}
            <div class="form_block">
                <input type="hidden" name="action" value="create" />
                <input type="submit" value="{% trans 'create' %}"/>
            </div>
        </fieldset>
    </form>
{% endblock %}
0
Gregory Presser

Je pense que vos problèmes peuvent résider dans l’affectation de données à un formulaire sans vérifier au préalable que la demande est POST

@login_required
def create_map(request, form_class=WayfinderMapForm, template_name="wayfinder/map create.html"):
  if request.method=='POST':
    wayfinder_map_form = form_class(request.user, data=request.POST, files=request.FILES)

    if wayfinder_map_form.is_valid():
      #save your data
      return HttpResponseRedirect(wayfinder_map.get_absolute_url())

  else:
    wayfinder_map_form=form_class(request.user)

 return render_to_response(template_name, {"wayfinder_map_form": wayfinder_map_form,}, context_instance=RequestContext(request))
0
czarchaic