为什么我在 Django 中得到 MultiValueDictKeyError?

Why I get MultiValueDictKeyError in django?

我有一个文章应用程序,在我向它添加图像字段 headimage 之前它曾经运行良好。

这是模型:

class Article(models.Model):
    nid = models.IntegerField(default=0)
    headimage = ImageWithThumbsField(upload_to='images', blank=True, sizes=((200,200),(400,400))
    title = models.CharField(max_length=100)
    author = models.CharField(max_length=100, blank=True)
    translator = models.CharField(max_length=100, blank=True)
    body = models.TextField()
    teaser = models.TextField('teaser', blank=True)
    created=models.DateTimeField(default=datetime.datetime.now)
    pub_date=models.DateTimeField(default=datetime.datetime.now)
    categories = models.ManyToManyField(Category, blank=True)
    slug = models.CharField(max_length=100, blank=True)
    tags = TaggableManager()

浏览量:

#@staff_member_required
def add_article(request):
    if request.method == 'POST':
        dform = ArticleForm(request.POST, request.FILES)
        if dform.is_valid():
            form = Article(headimage = request.FILES['headimage'])           
            form.save(commit=False)

            form.user = request.user
            form.save()
            form.save_m2m()

            messages.info(request, "article was added") 
            #args = {}
            post = Article.objects.latest('id')
            post_slug = post.slug
            return redirect('article.views.post_withslug', post_slug=post_slug)
        else:
            print "form not valid"

    if request.method == 'GET':
        form = ArticleForm()
        args = {}
        args.update(csrf(request))
        args['form'] = form
        return render(request, 'article/add_article.html', args)    

和模板:

<form   action="{% url "article.views.add_article" %}" method="post">{% csrf_token %}
 <div class="form-group">
    <label>Head Image</label>
    <input type="file" id="id_headimage" name="headimage" >
  </div>

 <div class="form-group">
    <label>Title</label>
    <input id="id_title" maxlength="100" name="title" type="text">
  </div>  

     <div class="form-group">
    <label>Author</label>
     <input id="id_author" maxlength="100" name="author" type="text">
  </div>

   <div class="form-group">
    <label>Translator</label>
     <input id="id_translator" maxlength="100" name="translator" type="text">
  </div>

      <div class="form-group">
    <label>Body</label>
     {% include "texteditor.html" %}
      <textarea id="id_body" name="body" rows="20" cols="180"></textarea>
  </div>

        <div class="form-group">
    <label>tags</label>
      <input id="id_tags" maxlength="100" name="tags" type="text">
  </div>


<input type="submit" name="submit"  value="Update" />
</div>

</form>

值得注意的是 1. 图像字段使用 this 优秀的图像调整大小片段,我在其他地方成功使用过。 2. 我收到错误,即使表格中没有张贴图片。

我已经尝试了不同的视图技巧,但我为此储存了很多小时。非常感谢您的帮助。

更新:这里是引用:

环境:

Request Method: POST
Request URL: http://127.0.0.1:8000/add/article

Django Version: 1.8
Python Version: 2.7.3
Installed Applications:
('django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'contact',
 'captcha',
 'article',
 'debug_toolbar',
 'userpics',
 'taggit')
Installed Middleware:
(u'debug_toolbar.middleware.DebugToolbarMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'django.middleware.security.SecurityMiddleware')


Traceback:
File "/home/randi/.env/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  132.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/randi/proj1/article/views.py" in add_article
  90.             form = Dastan(headimage = request.FILES['headimage'])           
File "/home/randi/.env/local/lib/python2.7/site-packages/django/utils/datastructures.py" in __getitem__
  322.             raise MultiValueDictKeyError(repr(key))

Exception Type: MultiValueDictKeyError at /add/article
Exception Value: "'headimage'"

我不确定这是否能解决问题,但我可以看到您正确保存了表单。无论发布的数据如何,您都在提交后初始化一个新对象。我看到您的模型中有必填字段

dform = ArticleForm(request.POST, request.FILES)
if dform.is_valid():

    ## In here you are creating a new object and try to save it. 
    # title, body are mandatory which will cause a crash 
    form = Article(headimage = request.FILES['headimage'])           
    form.save(commit=False)
    form.user = request.user
    form.save()
    form.save_m2m()


    # you should take the instance from the form. 
    form = dform.save(commit=False)
    form.user = request.user
    form.save()
    form.save_m2m()

您在 HTML 表单标签中遗漏了 enctype="multipart/form-data"。否则浏览器不会发送任何文件数据。

然而,您不应该在您的视图中直接引用 request.POSTrequest.FILES 指令:这就是表单的用途:

    dform = ArticleForm(request.POST, request.FILES)
    if dform.is_valid():
        article = dform.save(commit=False)

        article.user = request.user
        article.save()
        dform.save_m2m()