Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Form and File Uploading in Django

I have been trying to figure out what is going wrong when I try to submit a form. I get this response on the web page when I hit submit on the form:

Image:
    This field is required.

It seems to think I have not included an image in the form!

settings.py

...
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': '/path/to/myproject/database/sqlite.db'),
        'USER': '',
        'PASSWORD': '',
        'HOST': '',
        'PORT': '',
    }
}
...
MEDIA_ROOT = '/path/to/myproject/media/'
MEDIA_URL = '/media/'
...
INSTALLED_APPS = (
    ...
    'myapp',
)

models.py

from PIL import Image
from django import forms
from django.db import models
from django.forms import ModelForm

UPLOADER_CHOICES = (
    ('C', 'Common User'),
    ('N', 'Nutrition Kitchen'),
)

class Meal(models.Model):

    title       = models.CharField(max_length=100)
    slug        = models.SlugField(unique=True)
    image       = models.ImageField(upload_to='images/')
    serves      = models.IntegerField()
    ingredients = models.CharField(max_length=1000)
    instructions= models.CharField(max_length=1000)
    time_period = models.IntegerField()# in minutes
    uploader    = models.CharField(max_length=1, choices=UPLOADER_CHOICES)

def __unicode__(self):
    return self.title

forms.py

from django import forms
from meal.models import Meal

class MealForm(forms.Form):

    title       = forms.CharField(max_length=100)
    image       = forms.ImageField()
    ingredients = forms.CharField(max_length=1000)
    instructions= forms.CharField(max_length=1000)
    time_period = forms.IntegerField(required=False)
    serves      = forms.IntegerField(required=False)

views.py

from django.shortcuts import render_to_response
from django.template import RequestContext
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from meal.models import Meal
from meal.forms import MealForm

def upload(request):
    if request.method == 'POST':
        form = MealForm(request.POST, request.FILES)
        if form.is_valid():
            form.save()
            return render_to_response('upload.html', {'form': form})
    else:
        form = MealForm()
    return render_to_response('upload.html', {'form': form}, context_instance=RequestContext(request)
    )

upload.html

{% extends "base.html" %}
{% block content %}
{% if form.errors %}
        <p style="color: red;">
            Please correct the error{{ form.errors|pluralize }} below.
        </p>
{% endif %}
<div data-role="content" style="padding: 15px">
    <form action="" method="POST" enctype="multipart/form-data">
            {% csrf_token %}
            {{ form.errors }}
            {{ form.non_field_errors }}
            {{ form.as_table }}
        <input type="submit" value="Submit" id="Save">
    </form>
</div>
{% endblock %}

Does anyone have any ideas about what I could be doing wrong? I feel like I've tried everything.

like image 308
David Sawyer Avatar asked Oct 10 '12 05:10

David Sawyer


1 Answers

Okay, so it turned out that it was an issue with jQuery Mobile, which I didn't mention earlier. All I needed to do was change

<form action="" method="post" enctype="multipart/form-data">

to

<form action="" method="post" enctype="multipart/form-data" data-ajax="false">

because jQuery was trying to handle the POST for me. Apparently when you POST to the same URL in Django and want to handle it manually, you must include the

data-ajax="false"
like image 139
David Sawyer Avatar answered Sep 30 '22 19:09

David Sawyer