当需要 POST 类型时,请求类型为 GET
Request type is GET when POST type is needed
我正在尝试构建一个使用表单上传文件的简单 Django 应用程序,但是每当我 运行 我在本地主机上的应用程序时,我在尝试加载根页面时收到以下错误 - http://127.0.0.1:8000/
:
UnboundLocalError at /
local variable 'form' referenced before assignment
/Users/danieloram/PycharmProjects/FileUploaderProject/FileUploader/views.py in index
{'images': images, 'form': form},
...
▶ Local vars
以下是相关 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
因为 request
是 GET 方法..
任何人都可以帮助向我解释如何在 Django 中发出 POST 请求而不是针对此上下文的 GET 请求,从而解决我的错误并加载页面。我什至不在乎表格是否不起作用,我只是想获得解决方案方面的帮助。谢谢! PS - urls.py 文件设置正确。
解决方案
在这种情况下:
Get 请求在页面初始加载时执行。
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))
如果您在浏览器中提交表单,通常的工作流程是:
- 您使用 GET 请求浏览到 URL
- 浏览器用POST请求提交数据(因为表单有
action="POST"
)
- 如果表单有效,您将被重定向到成功的 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 文档很有用。示例视图与您尝试执行的操作非常相似。
您的问题不在于请求方法(显然您首先需要执行 GET 以呈现表单,以便您可以 POST 它),但事实上您 don 't 绑定名称 "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()
我正在尝试构建一个使用表单上传文件的简单 Django 应用程序,但是每当我 运行 我在本地主机上的应用程序时,我在尝试加载根页面时收到以下错误 - http://127.0.0.1:8000/
:
UnboundLocalError at /
local variable 'form' referenced before assignment
/Users/danieloram/PycharmProjects/FileUploaderProject/FileUploader/views.py in index
{'images': images, 'form': form},
...
▶ Local vars
以下是相关 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
因为 request
是 GET 方法..
任何人都可以帮助向我解释如何在 Django 中发出 POST 请求而不是针对此上下文的 GET 请求,从而解决我的错误并加载页面。我什至不在乎表格是否不起作用,我只是想获得解决方案方面的帮助。谢谢! PS - urls.py 文件设置正确。
解决方案
在这种情况下:
Get 请求在页面初始加载时执行。
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))
如果您在浏览器中提交表单,通常的工作流程是:
- 您使用 GET 请求浏览到 URL
- 浏览器用POST请求提交数据(因为表单有
action="POST"
) - 如果表单有效,您将被重定向到成功的 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 文档很有用。示例视图与您尝试执行的操作非常相似。
您的问题不在于请求方法(显然您首先需要执行 GET 以呈现表单,以便您可以 POST 它),但事实上您 don 't 绑定名称 "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()