首页 > 编程 > Python > 正文

在Django的视图中使用form对象的方法

2020-01-04 18:02:34
字体:
来源:转载
供稿:网友

这篇文章主要介绍了在Django的视图中使用form对象的方法,Django是Python丰富多彩的开发框架中最具有人气的一个,需要的朋友可以参考下

在学习了关于Form类的基本知识后,你会看到我们如何把它用到视图中,取代contact()代码中不整齐的部分。 一下示例说明了我们如何用forms框架重写contact():

 

 
  1. # views.py 
  2.  
  3. from django.shortcuts import render_to_response 
  4. from mysite.contact.forms import ContactForm 
  5.  
  6. def contact(request): 
  7. if request.method == 'POST'
  8. form = ContactForm(request.POST) 
  9. if form.is_valid(): 
  10. cd = form.cleaned_data 
  11. send_mail( 
  12. cd['subject'], 
  13. cd['message'], 
  14. cd.get('email''noreply@example.com'), 
  15. ['siteowner@example.com'], 
  16. return HttpResponseRedirect('/contact/thanks/'
  17. else
  18. form = ContactForm() 
  19. return render_to_response('contact_form.html', {'form': form}) 
  20.  
  21.  
  22. # contact_form.html 
  23.  
  24. <html> 
  25. <head> 
  26. <title>Contact us</title> 
  27. </head> 
  28. <body> 
  29. <h1>Contact us</h1> 
  30.  
  31. {% if form.errors %} 
  32. <p style="color: red;"
  33. Please correct the error{{ form.errors|pluralize }} below. 
  34. </p> 
  35. {% endif %} 
  36.  
  37. <form action="" method="post"
  38. <table> 
  39. {{ form.as_table }} 
  40. </table> 
  41. <input type="submit" value="Submit"
  42. </form> 
  43. </body> 
  44. </html> 

看看,我们能移除这么多不整齐的代码! Django的forms框架处理HTML显示、数据校验、数据清理和表单错误重现。

尝试在本地运行。 装载表单,先留空所有字段提交空表单;继而填写一个错误的邮箱地址再尝试提交表单;最后再用正确数据提交表单。 (根据服务器的设置,当send_mail()被调用时,你将得到一个错误提示。而这是另一个问题。)

改变字段显示

你可能首先注意到:当你在本地显示这个表单的时,message字段被显示成`` input type=”text”`` ,而它应该被显示成<`` textarea`` >。我们可以通过设置* widget* 来修改它:

 

 
  1. from django import forms 
  2.  
  3. class ContactForm(forms.Form): 
  4. subject = forms.CharField() 
  5. email = forms.EmailField(required=False) 
  6. message = forms.CharField(**widget=forms.Textarea** ) 

forms框架把每一个字段的显示逻辑分离到一组部件(widget)中。 每一个字段类型都拥有一个默认的部件,我们也可以容易地替换掉默认的部件,或者提供一个自定义的部件。

考虑一下Field类表现* 校验逻辑* ,而部件表现* 显示逻辑* 。

设置最大长度

一个最经常使用的校验要求是检查字段长度。 另外,我们应该改进ContactForm,使subject限制在100个字符以内。 为此,仅需为CharField提供max_length参数,像这样:

 

 
  1. from django import forms 
  2.  
  3. class ContactForm(forms.Form): 
  4. subject = forms.CharField(**max_length=100** ) 
  5. email = forms.EmailField(required=False) 
  6. message = forms.CharField(widget=forms.Textarea) 

选项min_length参数同样可用。

设置初始值

让我们再改进一下这个表单:为字subject段添加* 初始值* : "I love your site!" (一点建议,但没坏处。)为此,我们可以在创建Form实体时,使用initial参数:

 

 
  1. def contact(request): 
  2. if request.method == 'POST'
  3. form = ContactForm(request.POST) 
  4. if form.is_valid(): 
  5. cd = form.cleaned_data 
  6. send_mail( 
  7. cd['subject'], 
  8. cd['message'], 
  9. cd.get('email', `'noreply@example.com`_'), 
  10. [`'siteowner@example.com`_'], 
  11. return HttpResponseRedirect('/contact/thanks/'
  12. else
  13. form = ContactForm( 
  14. **initial={'subject''I love your site!'}** 
  15. return render_to_response('contact_form.html', {'form': form}) 

现在,subject字段将被那个句子填充。

请注意,传入* 初始值* 数据和传入数据以* 绑定* 表单是有区别的。 最大的区别是,如果仅传入* 初始值* 数据,表单是unbound的,那意味着它没有错误消息。

自定义校验规则

假设我们已经发布了反馈页面了,email已经开始源源不断地涌入了。 这里有一个问题: 一些提交的消息只有一两个字,我们无法得知详细的信息。 所以我们决定增加一条新的校验: 来点专业精神,最起码写四个字,拜托。

我们有很多的方法把我们的自定义校验挂在Django的form上。 如果我们的规则会被一次又一次的使用,我们可以创建一个自定义的字段类型。 大多数的自定义校验都是一次性的,可以直接绑定到form类.

我们希望`` message`` 字段有一个额外的校验,我们增加一个`` clean_message()`` 方法到`` Form`` 类:

 

 
  1. from django import forms 
  2.  
  3. class ContactForm(forms.Form): 
  4. subject = forms.CharField(max_length=100) 
  5. email = forms.EmailField(required=False) 
  6. message = forms.CharField(widget=forms.Textarea) 
  7.  
  8. def clean_message(self): 
  9. message = self.cleaned_data['message'
  10. num_words = len(message.split()) 
  11. if num_words < 4: 
  12. raise forms.ValidationError("Not enough words!"
  13. return message 

Django的form系统自动寻找匹配的函数方法,该方法名称以clean_开头,并以字段名称结束。 如果有这样的方法,它将在校验时被调用。

特别地,clean_message()方法将在指定字段的默认校验逻辑执行* 之后* 被调用。(本例中,在必填CharField这个校验逻辑之后。)因为字段数据已经被部分处理,所以它被从self.cleaned_data中提取出来了。同样,我们不必担心数据是否为空,因为它已经被校验过了。

我们简单地使用了len()和split()的组合来计算单词的数量。 如果用户输入字数不足,我们抛出一个forms.ValidationError型异常。这个异常的描述会被作为错误列表中的一项显示给用户。

在函数的末尾显式地返回字段的值非常重要。 我们可以在我们自定义的校验方法中修改它的值(或者把它转换成另一种Python类型)。 如果我们忘记了这一步,None值就会返回,原始的数据就丢失掉了。

指定标签

HTML表单中自动生成的标签默认是按照规则生成的:用空格代替下划线,首字母大写。如email的标签是"Email" 。(好像在哪听到过? 是的,同样的逻辑被用于模块(model)中字段的verbose_name值。 我们在第五章谈到过。)

像在模块中做过的那样,我们同样可以自定义字段的标签。 仅需使用label,像这样:

 

 
  1. class ContactForm(forms.Form): 
  2. subject = forms.CharField(max_length=100) 
  3. email = forms.EmailField(required=False, **label='Your e-mail address'** ) 
  4. message = forms.CharField(widget=forms.Textarea) 

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表