因此,Django表单的视图逻辑的标准模式是:
def contact(request):
if request.method == 'POST': # If the form has been submitted...
form = ContactForm(request.POST) # A form bound to the POST data
if form.is_valid(): # All validation rules pass
# Process the data in form.cleaned_data
# ...
return HttpResponseRedirect('/thanks/') # Redirect after POST
else:
form = ContactForm() # An unbound form
return render_to_response('contact.html', {
'form': form,
})
这在简单的情况下很好,但如果你的应用程序逻辑变得有点复杂,很容易陷入复杂的嵌套IF语句中。
任何人都可以分享他们自己的清洁方法,避免嵌套的IF和依赖于坠落案件的逻辑吗?
我对那些不依赖其他第三方应用的答案特别感兴趣。
答案 0 :(得分:12)
其中一个基于类的视图是FormView
(documentation)。您需要关注的两个主要方法是form_valid
和form_invalid
。
from django.views.generic import FormView
from myapp.forms import MyForm
class MyView(FormView):
template_name = 'edit_something.html'
form_class = MyForm
success_url = '/success/' # you should use `reverse`, but let's stay focused.
def form_valid(self, form):
"""
This is what's called when the form is valid.
"""
return super(MyView, self).form_valid(form)
def form_invalid(self, form):
"""
This is what's called when the form is invalid.
"""
return self.render_to_response(self.get_context_data(form=form))
或者,您可以覆盖post
,get
或put
方法,并根据每种请求处理表单。
答案 1 :(得分:3)
这是我发现的最短路法:
def contact(request):
# if it's POST request it'll have data else it'll be unbound
form = ContactForm(request.POST or None)
if request.method == 'POST' and form.is_valid():
# Process the data in form.cleaned_data
# ...
return HttpResponseRedirect('/thanks/') # Redirect after POST
return render_to_response('contact.html', { 'form': form, })
当然如果您不喜欢嵌套,如果您可以尝试倒转逻辑:
def contact(request):
template = 'contact.html'
if request.method != 'POST': # GET return:
return render_to_response(template, {'form': ContactForm()})
form = ContactForm(request.POST)
if not form.is_valid(): # FAIL return:
return render_to_response(template, {'form': form})
# here logic if user posted form and it's clean:
return HttpResponseRedirect('/thanks/')
答案 2 :(得分:2)
对于复杂场景,您应该考虑覆盖验证/清理过程中涉及的表单类的各种方法。 BaseForm
类定义了一个_post_clean()
方法,没有任何特别意味着被覆盖的行为。正确覆盖_clean()
也非常简单,如果你想在调用clean()
之前做某事,你也可以这样做。
阅读django.forms
的来源,可以让您更清楚地了解表单的工作方式,并根据您的需求找到合适的模式。
答案 3 :(得分:1)
到目前为止,我尝试使视图功能更清晰:
BUT 的
django 1.3现在有基于类的视图..这给了一个很大的机会
使视图可扩展..使mixins ..不要一遍又一遍地写保存。
我个人想尝试一下,并尝试用类的新风格写django的东西。
答案 4 :(得分:1)
这些情况的主要复杂性来源是在同一视图函数中处理GET和POST。将每个方法的逻辑分离到自己的视图中,事情变得更加清晰。
唯一的重复是渲染表格html,但这个特殊部分对于两种情况都是简洁而有意义的(即不是样板文件),所以这是可以接受的。