Django:将值从模板传递到视图
Django: Passing value from template to view
我遇到过这种情况:
点击 html 提交按钮,我调用 views.stream_response
which "activates" views.stream_response_generator
which "activates" stream.py 和 return 一个 StreamingHttpResponse 并且我每秒看到一个累进数字,直到 m
在 /stream_response/
:
1
2
3
4
5
6
7
8 //e.g. my default max value for m
stream.py
from django.template import Context, Template
import time
def streamx(m):
lista = []
x=0
while len(lista) < m:
x = x + 1
time.sleep(1)
lista.append(x)
yield "<div>%s</div>\n" % x #prints on browser
print(lista) #print on eclipse
return (x)
views.py
def stream_response(request): // unified the three functions as suggested
if request.method == 'POST':
form = InputNumeroForm(request.POST)
if form.is_valid():
m = request.POST.get('numb', 8)
resp = StreamingHttpResponse(stream.streamx(m))
return resp
forms.py
from django.db import models
from django import forms
from django.forms import ModelForm
class InputNumero(models.Model):
m = models.IntegerField()
class InputNumeroForm(forms.Form):
class Meta:
models = InputNumero
fields = ('m',)
urls.py
...
url(r'^homepage/provadata/$', views.provadata),
url(r'^stream_response/$', views.stream_response, name='stream_response'),
...
homepage/provadata.html
<form id="streamform" action="{% url 'stream_response' %}" method="POST">
{% csrf_token %}
{{form}}
<input id="numb" type="number" />
<input type="submit" value="to view" id="streambutton" />
</form>
如果我删除“8”并仅使用 m = request.POST.get('numb')
我得到:
ValueError at /stream_response/ The view homepage.views.stream_response didn't return an HttpResponse object.
It returned None instead.
所以,如果我尝试提交,它只需要默认值 8(并且有效)但它不会接受我的表单输入。怎么了?
-->更新:@Tanguy Serrat 建议:
views.py
def stream_response(request):
form = InputNumeroForm()
if request.method == 'POST':
form = InputNumeroForm(data=request.POST)
if form.is_valid():
#Accessing the data in cleaned_data
m = form.cleaned_data['numero']
print("My form html: %s" % form)
print ("My Number: %s" % m) #watch your command line
print("m = ", m)
resp = StreamingHttpResponse(stream.streamx(m))
return resp
#If not post provide the form here in the template :
return render(request, 'homepage/provadata.html', {'form': form,})
forms.py
class InputNumeroForm(forms.Form):
numero = models.IntegerField()
homepage/provadata.py
<form action="/stream_response/" method="POST">
{% csrf_token %}
{{form}} <!--issue: does not appear on the html !!!!!-->
<input type="number" name="numero" /> <!--so I write this-->
<input type="submit" value="to view" />
</form>
如果我给出输入,例如7 来自键盘:
KeyError at /stream_response/
'numero'
同时
如果我写 m = request.POST.get('numero')
,在命令行中我有:
...
My form html:
My Number: 7
m = 7
...
while len(lista) < m:
TypeError: unorderable types: int() < str()
Django 视图必须 return 一个 HttpResponse 对象。考虑到您引用的其他两个函数各只有一行,最好将所有内容都放在一个函数中,或者至少将 StreamingHttpResponse 移至主函数。
编辑:必须给 StreamingResponseHttp 一个可迭代对象,所以回到 stream.py,尝试去掉 return 和打印函数(我去掉了多余的东西为了实验)。这在 shell.
对我有用
def streamx(m):
lista = []
x=0
while len(lista) < m:
x = x + 1
time.sleep(1)
lista.append(x)
yield "<div>%s</div>\n" % x #prints on browser
#c = Context({'x': x})
#yield Template('{{ x }} <br />\n').render(c)
def stream_response(request):
if request.method == 'POST':
form = InputNumeroForm(request.POST)
if form.is_valid():
m = request['numb']
resp = StreamingHttpResponse(streamx(m))
return resp
我发现您发布的代码存在一些问题:
您的表单字段缺少 'name' 属性,因此为该字段设置的值将不会传递给您的代码。这就是为什么您的 request.POST.get('numb')
returns None 除非您提供默认值 (8)。
试试这个:
<input id="numb" name="numb" type="number" />
此外,我注意到您在您的表单中使用了 models.IntegerField
- 您为什么要在这里使用模型字段?
对您来说更好的方法可能是将 numb 字段添加到您的表单,然后从表单的清理数据中检索值:form.cleaned_data['numb']
而不是 POST 数据。
希望这能让你继续前进。
编辑: ModelForm 部分已删除,无需将数据保存在数据库中,因此以这种方式使用经典形式:
方法 1: 使用 Django 的无模型的经典形式
在你的forms.py
from django import forms
class InputNumeroForm(forms.Form):
numero = forms.IntegerField()
在你的views.py
from django.shortcuts import render
def stream_response(request):
form = InputNumeroForm()
if request.method == 'POST':
form = InputNumeroForm(data=request.POST)
if form.is_valid():
#Accessing the data in cleaned_data
m = form.cleaned_data['numero']
print "My Number %s" % m #watch your command line
resp = StreamingHttpResponse(stream.streamx(m))
return resp
#If not post provide the form here in the template :
return render(request, 'homepage/provadata.html', {
'form': form,
})
在您的模板中:
<form id="streamform" action="{% url 'stream_response' %}" method="POST">
{% csrf_token %}
{{ form }}
<input type="submit" value="to view" id="streambutton" />
</form>
为了澄清一点,Django 中有两种类型的表单:
- 不需要保存在数据库中的经典表单
- 允许您创建基于数据库模型的表单的模型表单,即(您可以向数据库添加一行或编辑一行)
在这里您不需要将号码保存在数据库中,因此您使用经典形式:
https://docs.djangoproject.com/en/1.8/topics/forms/
方法二:不使用Django Form
对于像您这样的非常简单的表格:
在views.py
from django.shortcuts import render
def stream_response(request):
if request.method == 'POST':
if request.POST.get('numero', False):
m = int(request.POST['numero'])
print "My Number %s" % m #watch your command line
resp = StreamingHttpResponse(stream.streamx(m))
return resp
return render(request, 'homepage/provadata.html')
在您的模板中:
<form id="streamform" action="{% url 'stream_response' %}" method="POST">
{% csrf_token %}
<input type="number" name="numero" />
<input type="submit" value="to view" id="streambutton" />
</form>
我遇到过这种情况:
点击 html 提交按钮,我调用 views.stream_response
which "activates" views.stream_response_generator
which "activates" stream.py 和 return 一个 StreamingHttpResponse 并且我每秒看到一个累进数字,直到 m
在 /stream_response/
:
1
2
3
4
5
6
7
8 //e.g. my default max value for m
stream.py
from django.template import Context, Template
import time
def streamx(m):
lista = []
x=0
while len(lista) < m:
x = x + 1
time.sleep(1)
lista.append(x)
yield "<div>%s</div>\n" % x #prints on browser
print(lista) #print on eclipse
return (x)
views.py
def stream_response(request): // unified the three functions as suggested
if request.method == 'POST':
form = InputNumeroForm(request.POST)
if form.is_valid():
m = request.POST.get('numb', 8)
resp = StreamingHttpResponse(stream.streamx(m))
return resp
forms.py
from django.db import models
from django import forms
from django.forms import ModelForm
class InputNumero(models.Model):
m = models.IntegerField()
class InputNumeroForm(forms.Form):
class Meta:
models = InputNumero
fields = ('m',)
urls.py
...
url(r'^homepage/provadata/$', views.provadata),
url(r'^stream_response/$', views.stream_response, name='stream_response'),
...
homepage/provadata.html
<form id="streamform" action="{% url 'stream_response' %}" method="POST">
{% csrf_token %}
{{form}}
<input id="numb" type="number" />
<input type="submit" value="to view" id="streambutton" />
</form>
如果我删除“8”并仅使用 m = request.POST.get('numb')
我得到:
ValueError at /stream_response/ The view homepage.views.stream_response didn't return an HttpResponse object. It returned None instead.
所以,如果我尝试提交,它只需要默认值 8(并且有效)但它不会接受我的表单输入。怎么了?
-->更新:@Tanguy Serrat 建议:
views.py
def stream_response(request):
form = InputNumeroForm()
if request.method == 'POST':
form = InputNumeroForm(data=request.POST)
if form.is_valid():
#Accessing the data in cleaned_data
m = form.cleaned_data['numero']
print("My form html: %s" % form)
print ("My Number: %s" % m) #watch your command line
print("m = ", m)
resp = StreamingHttpResponse(stream.streamx(m))
return resp
#If not post provide the form here in the template :
return render(request, 'homepage/provadata.html', {'form': form,})
forms.py
class InputNumeroForm(forms.Form):
numero = models.IntegerField()
homepage/provadata.py
<form action="/stream_response/" method="POST">
{% csrf_token %}
{{form}} <!--issue: does not appear on the html !!!!!-->
<input type="number" name="numero" /> <!--so I write this-->
<input type="submit" value="to view" />
</form>
如果我给出输入,例如7 来自键盘:
KeyError at /stream_response/
'numero'
同时
如果我写 m = request.POST.get('numero')
,在命令行中我有:
...
My form html:
My Number: 7
m = 7
...
while len(lista) < m:
TypeError: unorderable types: int() < str()
Django 视图必须 return 一个 HttpResponse 对象。考虑到您引用的其他两个函数各只有一行,最好将所有内容都放在一个函数中,或者至少将 StreamingHttpResponse 移至主函数。
编辑:必须给 StreamingResponseHttp 一个可迭代对象,所以回到 stream.py,尝试去掉 return 和打印函数(我去掉了多余的东西为了实验)。这在 shell.
对我有用def streamx(m):
lista = []
x=0
while len(lista) < m:
x = x + 1
time.sleep(1)
lista.append(x)
yield "<div>%s</div>\n" % x #prints on browser
#c = Context({'x': x})
#yield Template('{{ x }} <br />\n').render(c)
def stream_response(request):
if request.method == 'POST':
form = InputNumeroForm(request.POST)
if form.is_valid():
m = request['numb']
resp = StreamingHttpResponse(streamx(m))
return resp
我发现您发布的代码存在一些问题:
您的表单字段缺少 'name' 属性,因此为该字段设置的值将不会传递给您的代码。这就是为什么您的 request.POST.get('numb')
returns None 除非您提供默认值 (8)。
试试这个:
<input id="numb" name="numb" type="number" />
此外,我注意到您在您的表单中使用了 models.IntegerField
- 您为什么要在这里使用模型字段?
对您来说更好的方法可能是将 numb 字段添加到您的表单,然后从表单的清理数据中检索值:form.cleaned_data['numb']
而不是 POST 数据。
希望这能让你继续前进。
编辑: ModelForm 部分已删除,无需将数据保存在数据库中,因此以这种方式使用经典形式:
方法 1: 使用 Django 的无模型的经典形式
在你的forms.py
from django import forms
class InputNumeroForm(forms.Form):
numero = forms.IntegerField()
在你的views.py
from django.shortcuts import render
def stream_response(request):
form = InputNumeroForm()
if request.method == 'POST':
form = InputNumeroForm(data=request.POST)
if form.is_valid():
#Accessing the data in cleaned_data
m = form.cleaned_data['numero']
print "My Number %s" % m #watch your command line
resp = StreamingHttpResponse(stream.streamx(m))
return resp
#If not post provide the form here in the template :
return render(request, 'homepage/provadata.html', {
'form': form,
})
在您的模板中:
<form id="streamform" action="{% url 'stream_response' %}" method="POST">
{% csrf_token %}
{{ form }}
<input type="submit" value="to view" id="streambutton" />
</form>
为了澄清一点,Django 中有两种类型的表单:
- 不需要保存在数据库中的经典表单
- 允许您创建基于数据库模型的表单的模型表单,即(您可以向数据库添加一行或编辑一行)
在这里您不需要将号码保存在数据库中,因此您使用经典形式: https://docs.djangoproject.com/en/1.8/topics/forms/
方法二:不使用Django Form 对于像您这样的非常简单的表格:
在views.py
from django.shortcuts import render
def stream_response(request):
if request.method == 'POST':
if request.POST.get('numero', False):
m = int(request.POST['numero'])
print "My Number %s" % m #watch your command line
resp = StreamingHttpResponse(stream.streamx(m))
return resp
return render(request, 'homepage/provadata.html')
在您的模板中:
<form id="streamform" action="{% url 'stream_response' %}" method="POST">
{% csrf_token %}
<input type="number" name="numero" />
<input type="submit" value="to view" id="streambutton" />
</form>