Django:将值从模板传递到视图

Tri*_*rix 3 django streaming httpresponse django-forms django-views

我有这种情况:

点击一个HTML提交按钮,我把views.stream_response它"激活" views.stream_response_generator其"激活" stream.py并返回StreamingHttpResponse,我看到一个渐进的数每秒达m/stream_response/:

1
2
3
4
5
6
7
8  //e.g. my default max value for m
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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',)
Run Code Online (Sandbox Code Playgroud)

urls.py

...
url(r'^homepage/provadata/$', views.provadata),    
url(r'^stream_response/$', views.stream_response, name='stream_response'),
...
Run Code Online (Sandbox Code Playgroud)

主页/ 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>
Run Code Online (Sandbox Code Playgroud)

如果我删除"8"并仅使用m = request.POST.get('numb')我获得:

/ stream_response /上的ValueError视图homepage.views.stream_response未返回HttpResponse对象.它返回了None.

所以,如果我尝试提交,它只需要默认值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,})
Run Code Online (Sandbox Code Playgroud)

forms.py

class  InputNumeroForm(forms.Form):
    numero = models.IntegerField()
Run Code Online (Sandbox Code Playgroud)

主页/ 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>
Run Code Online (Sandbox Code Playgroud)

如果我从键盘输入例如7:

/ stream_response /的KeyError/

'NUMERO' 它需要输入数字

如果我写m = request.POST.get('numero'),在命令行我有:

...
My form html: 
My Number: 7
m =  7
...
   while len(lista) < m:
   TypeError: unorderable types: int() < str()
Run Code Online (Sandbox Code Playgroud)

Tan*_*rat 5

编辑:删除了ModelForm部分,无需将数据保存在DB中,因此使用经典表单这样:

方法1:使用Django的没有模型的经典表单

在你的forms.py中

from django import forms

class InputNumeroForm(forms.Form):

    numero = forms.IntegerField()
Run Code Online (Sandbox Code Playgroud)

在你的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,
    })
Run Code Online (Sandbox Code Playgroud)

在您的模板中:

<form id="streamform" action="{% url 'stream_response' %}" method="POST">
  {% csrf_token %}
  {{ form }}
  <input type="submit" value="to view" id="streambutton" />
</form>
Run Code Online (Sandbox Code Playgroud)

为了澄清一下,Django中有两种类型的表单:

  • 经典表单,不需要保存在数据库中
  • 模型表单,允许您创建基于数据库模型的表单,即(您可以向数据库添加一行或编辑一行)

在这里,您无需在数据库中保存您的号码,因此您可以使用经典表格:https: //docs.djangoproject.com/en/1.8/topics/forms/

方法2:不使用Django表单对于非常简单的表单,如您的情况:

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')
Run Code Online (Sandbox Code Playgroud)

在您的模板中:

<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>
Run Code Online (Sandbox Code Playgroud)

  • KeyError是正常的,因为表单未在模板上呈现.确保你在views.py中使用`return render(request,'homepage/provadata.html',{'form':form,})`来做你给我的.如果你无法实现这一点,你可以添加:`<input type ="number"name ="numero"/>`但这不能帮助你弄清楚为什么你不能渲染{{form}} (2认同)