Django中的表单和文件上传

时间:2012-10-10 05:54:54

标签: django forms file-upload

当我尝试提交表单时,我一直试图弄清楚出了什么问题。 当我在表单上点击提交时,我在网页上得到了这个回复:

Image:
    This field is required.

似乎我认为我没有在表单中包含图片!

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 %}

有没有人对我可能做错了什么有任何想法?我觉得我已经尝试了一切。

6 个答案:

答案 0 :(得分:5)

好的,事实证明这是jQuery Mobile的一个问题,我之前没有提到过。我需要做的就是改变

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

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

因为jQuery试图为我处理POST。显然,当您在Django中POST到同一个URL并希望手动处理它时,您必须包含

data-ajax="false"

答案 1 :(得分:1)

在forms.py

中尝试此操作
image = forms.ImageField(widget=forms.FileInput())

我希望它有所帮助

答案 2 :(得分:1)

在你的模特中你有

models.ImageField(upload_to='images/')

此字段是必填字段。 将其更改为

models.ImageField(upload_to='images/', blank=True, null=True)

将不需要

答案 3 :(得分:1)

这一行:

form.save()

......什么都不做。您应该从表单处理cleaning_data,或者使用具有save()方法的ModelForm。

Django Forms | Django ModelForms

答案 4 :(得分:0)

好像你错过了这个,

class MealForm(forms.Form):
    class Meta:
        model = Meal 
    title = forms.CharField(max_length=100)

答案 5 :(得分:0)

尝试使用 modelform 而不是常规表单

class MealForm(forms.ModelForm): #Note, this is a Modelform, not a regular old form.
    class Meta: 
        model = Meal