【问题标题】:Request type is GET when POST type is needed需要 POST 类型时,请求类型为 GET
【发布时间】:2015-07-15 15:20:48
【问题描述】:

我正在尝试构建一个使用表单上传文件的简单 Django 应用程序,但是每当我在本地主机上运行我的应用程序时,尝试加载根页面时都会出现以下错误 - http://127.0.0.1:8000/

UnboundLocalError at /

赋值前引用的局部变量'form'

/Users/danieloram/PycharmProjects/FileUploaderProject/FileUploader/views.py in index

  1.                                    {'images': images, 'form': form},
    

    ...

▶ 局部变量

这里是相关view.py、models.py和index.html(问题中的视图)文件的代码:

views.py ##

from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from django.template import RequestContext

#import models and forms
from FileUploader.models import Image
from FileUploader.forms import ImageUploadForm

# Create your views here.

#this view will respond to file uploads
def index(request):
    print("View loaded")
    if request.method =='POST':
        #create a form from the model I made
        form = ImageUploadForm(request.POST, request.FILES)
        #check form contains no errors
        if form.is_valid():
            #create a new image and save it! file param must be name of attribute in ImageUploadForm
            newImage = Image(imageFile = request.FILES['imageFile'])
            newImage.save()
            #redirect to success page!
            return HttpResponseRedirect('/success/')
        else:
            #create an empty form if it failed
            form = ImageUploadForm()
    else:
        #view will not load as error thrown from nothing being assigned to the form.
        print("Form method was not POST! nothing was assigned to the form and it will fail.")
    images = Image.objects.all()
    #render the page and pass the dictionary to the view
    return render_to_response('index.html',
                              {'images': images, 'form': form},
                              context_instance=RequestContext(request))
def success(request):
    debug = str(request)
    return render(request, 'success.html', {'debug': debug})

models.py ##

from django.db import models

# Create your models here.

#simple model for creating image objects
class Image(models.Model):
    imageFile = models.FileField(upload_to='images/%Y/%m/%d')

index.html ##

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    {% load staticfiles %}
    <link rel="stylesheet" type="text/css" href="{% static "style.css" %}">
    <title>Daniel Oram's FileUploading Django Project</title>
</head>
<body>
<div class="container">
    <div id="buffer"></div>
    <div id="panel">
        <p>Choose a file to upload</p>
        <form id="form" action="{% url 'index' %}" method="post" enctype="multipart/form-data">
            <input id="input" type="file" value="Enter Image here for upload" width="100">
            <input type="submit" value="Submit" width="50">
            <!-- I need csrf_token because I used RequestContext in the view -->
            {% csrf_token %}
            <p>{{ form.non_field_errors }}</p>
            <p>{{ form.imageFile.label }} {{ form.imageFile.help_text }}</p>
            <p>
                {{ form.imageFile.error_messages }}
                {{ form.imageFile }}
            </p>
        </form>
    </div>
    <!--List the files already uploaded to the webapp. -->
    <div id="list_of_Images">
        {% if images %}
        <ul>
            <!--Iterate Images stored in media directory and display a link for each -->
            {% for image in images %}
            <li><a href='{{ image.imageFile.url }}'>{{ image.imageFile.name }}</a></li>
            {% endfor %}
        </ul>
        {% else %}
        <p>There are no Images that have been previously uploaded :(</p>
        {% endif %}
    </div>
</div>
</body>
</html>

我的调试工作

到目前为止,我通过调试发现该错误是由于views.py的index方法中没有初始化form变量引起的,因为if request.method =='POST':总是计算为False,因为@ 987654329@ 是一个 GET 方法..

谁能帮我解释一下如何在 Django 中发出 POST 请求,而不是这个上下文的 GET 请求,从而解决我的错误并加载页面。我什至不在乎表格是否不起作用,我只是想要一个解决方案的帮助。谢谢! PS - urls.py 文件设置正确。

解决方案

在这种情况下:

  • 在页面初始加载时执行获取请求。

  • 提交表单数据时发出post请求。

  • 需要初始化表单变量,以便在初始页面加载时传递给视图。

  • 用于初始页面加载的 Else 子句初始化表单附加到错误的 if 语句并且无法访问。

正确的索引方法

def index(request):
    print("View loaded")
    if request.method =='POST':
        form = ImageUploadForm(request.POST, request.FILES)
        if form.is_valid():
            newImage = Image(imageFile = request.FILES['imageFile'])
            newImage.save()
            return HttpResponseRedirect('/success/')       
    else:
        form = ImageUploadForm()
    images = Image.objects.all()
    return render_to_response('index.html',
                              {'images': images, 'form': form},
                              context_instance=RequestContext(request))

【问题讨论】:

    标签: python django post django-forms django-views


    【解决方案1】:

    如果您在浏览器中提交表单,通常的工作流程是:

    1. 您通过 GET 请求浏览到 URL
    2. 浏览器通过POST请求提交数据(因为表单有action="POST"
    3. 如果表单有效,您将被重定向到成功的 URL

    因此,与其询问如何将所有请求更改为 POST,不如让您的代码适用于初始 GET 请求。您可以通过在 else 分支中创建一个未绑定的表单来做到这一点。

        if request.method =='POST':
            # create a form bound to the post data
            form = ImageUploadForm(request.POST, request.FILES)
            ...
        else:
            # create an unbound form for the original GET request
            form = ImageUploadForm()
            ...
    

    您可能会发现阅读有关 working with forms 的 Django 文档很有用。示例视图与您尝试做的非常相似。

    【讨论】:

    • 天哪,我在错误的 if 语句中添加了 else 子句……太简单了! >_
    【解决方案2】:

    您的问题不在于请求方法(显然,您首先需要执行 GET 以呈现表单,以便您可以发布它),而是您绑定名称“form” wjen 它是一个 GET:

    def index(request):
        print("View loaded")
        if request.method =='POST':
            form = ImageUploadForm(request.POST, request.FILES)
            if form.is_valid():
                newImage = Image(imageFile = request.FILES['imageFile'])
                newImage.save()
                return HttpResponseRedirect('/success/')    
    
            # this part is wrong : if the validation failed,
            # you don't want to create a new empty form but
            # redisplay the failed form so you can display
            # the validation errors
            #else:
            #    #create an empty form if it failed
            #    form = ImageUploadForm()
    
        else:
            ## view will not load as error thrown 
            ## from nothing being assigned to the form.
            # => actually the real error is that you dont 
            #    define the *name* 'form' at all
            #    in this branch...
            #    IOW that's where you want to create 
            #    an "empty" form so the user can fill and
            #    submit it
            form = ImageUploadForm()
    

    【讨论】:

      猜你喜欢
      • 2015-01-05
      • 1970-01-01
      • 2019-12-30
      • 2017-03-03
      • 2011-08-05
      • 2010-09-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多