我想要一个简单的表单,一旦填充,将指向不同的网页或如果无效则保留在同一页面上。页面应该有一个文本框并提交表单,一旦用户输入任何内容,它应该指向一个单独的页面。
我的目录结构如下:
appName/
app/
forms.py
urls.py
views.py
templates/
app/
goodbye.html
name.html
library.html
thanks.html
appName/
settings.py
urls.py
我的 app / urls.py 如下:
from django.conf.urls import url
from . import views
app_name = 'app'
urlpatterns = [
url(r'^$', views.index2, name = 'index'),
url(r'^hello/$', views.hello, name = 'hello'),
url(r'^goodbye/$', views.goodbye, name = 'goodbye'),
#url(r'^library$', views.library, name = 'library'),
url(r'^library/$', views.library, name = 'library'),
url(r'^library/(?P<book_id>[0-9]+)/$', views.book, name = 'book'),
url(r'^getname/$', views.get_name, name = 'get_name'),
url(r'^your-name/$',views.get_name, name='get_name'),
url(r'^thanks/$',views.say_thanks,name='thanks'),
#url(r'^thanks/(?P<name_id>[a-zA-Z]+)/$', views.say_thanks,name='thanks'),
]
我的 forms.py 是:
来自django导入表格
class NameForm(forms.Form):
your_name = forms.CharField(label = 'Your name', max_length=100)
我的 app / views.py 是:
from django.http import HttpResponse
from django.template import loader
from django.shortcuts import render
from django.http import HttpResponseRedirect
#forms
from .forms import NameForm
# Create your views here.
def index2(request):
return HttpResponse("hello world")
def hello(request):
text = """<h1>Welcome to my app! </h1>"""
return HttpResponse(text)
def goodbye(request):
template = loader.get_template("app/goodbye.html")
context = {
'output' : 'This is output from goodby views.py request handler'
}
return HttpResponse(template.render(context,request))
def library(request):
template = loader.get_template("app/library.html")
context = {
'output' : 'Welcome to the libary!!'
}
return HttpResponse(template.render(context, request))
def book(request, book_id):
return HttpResponse("You're looking at book %s. " % book_id)
def get_name(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = NameForm(request.POST)
# check whether it's valid:
if form.is_valid():
#process the data in form.cleaned_data as required
locationGo = "/thanks/"
template = loader.get_template("app/thanks.html")
return HttpResponse(template.render({'name':'name'},request))
else:
form = NameForm()
template = loader.get_template("app/name.html")
context = {'form': form}
return HttpResponse(template.render(context, request))
def say_thanks(request):
template = loader.get_template("app/thanks.html")
return HttpResponse(template.render({'name': 'name'},request))
我的模板包括:
name.html :
<form action = "/getname/" method = "post">
{% csrf_token %}
{{ form }}
<input type = "submit" value = "Submit" />
</form>
goodbye.html
<h1>Goodbye to Template Romance</h1>
<a href="{% url 'app:index' %}">Go Back</a>
thanks.html
Thanks {{name}}!
我喜欢的目的是:
访问以下网站的用户:website.com/getname/以显示name.html文件(确实如此)
如果用户点击提交以停留在同一页面(website.com/getname/)(它没有 - 它给出:ValueError at / getname / - &gt; view app.views.get_name没有返回一个HttpResponse对象。它返回了None。
如果用户在提交字段中输入,则会被重定向到website.com/thanks/(它有点类似。它目前正在加载thanks.html模板,但网址仍在网站上的getName /)
在get_name(request):函数内部,POST和GET if ... else似乎没有基于Submit按钮触发,并且它似乎没有加载正确的页面,或者更改处理后的当前URL地址。我已经尝试使用HttpRedirect(),但是,我也想传递表单数据(这是另一个问题)。
任何建议都会有很大的帮助!
答案 0 :(得分:5)
您的第一个问题是,当请求方法发布且表单无效时,您没有返回响应。您可以通过更改视图的缩进来解决此问题,以便始终在视图的末尾返回响应。
def get_name(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
...
else:
form = NameForm()
template = loader.get_template("app/name.html")
context = {'form': form}
return HttpResponse(template.render(context, request))
如果您想重定向到/thanks/
视图,则可以使用重定向快捷方式。
if form.is_valid():
return redirect('thanks')
请注意,无法重定向和传递表单数据(有关说明,请参阅this question)。您应该在重定向之前使用数据进行任何处理。您可以在重定向之前使用messages framework创建消息'Thanks <name>'
。
这是有效的,因为您的网址格式中有name='thanks'
。
您可以使用render
快捷方式简化视图。而不是
template = loader.get_template("app/name.html")
context = {'form': form}
return HttpResponse(template.render(context, request))
你可以这样做:
return render(request, "app/name.html", context)
请记住为快捷方式添加导入:
from django.shortcuts import redirect, render