一、在views中的使用
下面从我自己做的小demo开始记录起。
1 #models.py 2 class Other2(models.Model): 3 name = models.CharField(max_length=30) 4 age = models.IntegerField() 5 email = models.EmailField() 6 7 class META: 8 db_table='Demo'
1 #coding=utf-8 2 #forms.py 3 from django import forms 4 5 class ContactForm(forms.Form): 6 name = forms.CharField(max_length=30) 7 age = forms.IntegerField() 8 email = forms.EmailField(required=False) 9 #错误提示类,Once you’ve done that, rows will be given "error" and/or "required" classes, as needed 10 error_css_class='error' 11 required_css_class = 'required' 12 13 #自定义错误列表格式 14 from django.forms.util import ErrorList 15 class DivErrorList(ErrorList): 16 def __unicode__(self): 17 return self.as_divs() 18 19 def as_divs(self): 20 if not self: 21 return u'' 22 return u'<div class="errorlist">%s</div>' % ''.join([u'<div class="error">%s</div>' %e for e in self])
views.py def form_test(request): """ ---------------------------------------------- Function: form测试 DateTime: 2013/9/9 ---------------------------------------------- """ other = Other2.objects.all() if request.method == 'POST': form = ContactForm(request.POST) #绑定post数据 if form.is_valid(): #如果通过验证 #数据清理 name = form.cleaned_data['name'] age = form.cleaned_data['age'] email = form.cleaned_data['email'] Other2.objects.create(name=name,age=age,email=email) return render_to_response('form/form.html',{'form':form,'other':other}) else: #如果表单未被提交,则一个未绑定的表单实例被创建 form = ContactForm(initial={'name':'Hi,here','email':'@'}) #未绑定的表单 return render_to_response('form/form.html',{'form':form,'other':other})
html: <form action='/form/form/' method='post'>{% csrf_token %} {{form.as_table}} <input type='submit' value='Submit' class='btn'> </form> <hr> {% for obj in other %} <p>Name: {{obj.name}}</p> {% endfor %}
除urls外基本上构成了django 表单的一整套。接下来就是变化子重置一些代码了。
二、自定义表单模板
上一节学了很多关于自定义表单显示的知识,在这里就运用在模板里面吧。
1、单个显示
<form action="/contact/" method="post"> {{ form.non_field_errors }} <div class="field"> {{ form.name.errors }} <label for="id_name">Name:</label> {{ form.name}} </div> <div class="field"> {% if form.age.errors %} {% for err in form.age.errors %} <p>{{err|escape}}</p> {% endfor %} {% endif %} <label for="id_age">Your age:</label> {{ form.age}} </div> <div class="field"> {{ form.email.errors }} <label for="id_email">Your email :</label> {{ form.email}} </div> <p><input type="submit" value="Send message" /></p> </form>
{{form.字段名}}显示对应的字段
{{form.字段名.errors}}显示字段对应的错误提示
2、循环输出
同时可以一次循环输出所有表单字段
<form action='/form/form/' method='post'>{% csrf_token %} {% for field in form %} <div class='field'> {{field.errors}}<!-- 错误提示 --> {{field.label_tag}}:{{field}}<!-- label标签:表单字段 --> </div> {% endfor %} <input type='submit' value='Submit' class='btn'> </form>
在以上循环中{{field}}是绑定字段的实例,它也具有如下属性:
{{field.label}}:字段标签,不含html代码,如:Name
{{field.label_tag}}:含html代码的字段标签,如<label id="id_name">Name:</label>
{{field.html_name}}:字段的html名称,如:name、age
{{field.help_text}}:字段帮助文本
{{field.errors}}:字段错误列表,可循环
3、对于表单的可见与不可见
可以使用hidden_fields() and visible_fields()
对于不可见的表单字段就不显示错误信息提示,对于可见的就正常显示,如下:
<form action="/contact/" method="post"> {% for field in form.visible_fields %} <div class="fieldWrapper"> {# Include the hidden fields in the form #} {% if forloop.first %} {% for hidden in form.hidden_fields %} {{ hidden }} {% endfor %} {% endif %} {{ field.errors }} {{ field.label_tag }}: {{ field }} </div> {% endfor %} <p><input type="submit" value="Send message" /></p> </form>
4、重复使用
如果多个模板重复使用一个表单,则可以使用{% include 'xxx.html ' %}(假设xxx.html代码中含有该表单)
<form action="/contact/" method="post"> {% include "form_snippet.html" %} <p><input type="submit" value="Send message" /></p> </form> # In form_snippet.html: {% for field in form %} <div class="fieldWrapper"> {{ field.errors }} {{ field.label_tag }}: {{ field }} </div> {% endfor %}
三、深入表单类
不得不参考:https://docs.djangoproject.com/en/1.2/topics/forms/modelforms/
这里总结性的笔记如下:
1、从一个django model中创建表单类(form model)
这是一个趋势,django model与 form model紧密的结合。
#coding=utf-8 from django.db import models from django.forms import ModelForm #导入ModelForm """从一个django model中创建表单类(form model)""" # Comment class Comment(models.Model): #.... class CommentForm(ModelForm): class Meta: model = Comment #.... #Creating a form to add an comment. form = CommentForm() # Creating a form to change an existing comment. >>> comment = Comment.objects.get(pk=1) >>> form = CommentForm(instance=comment)
注意:
(1)、字段类型的对应,django model的字段类型对应到form的字段类型,这里列举一下几个重要的:
Model field | Form field |
BooleanField | BooleanField |
CharField | CharField with max_length |
DateField | DateField |
DateTimeField | DateTimeField |
FileField | FileField |
ForeignKey | ModelChoiceField |
IntegerField | IntegerField |
ManyToManyField | ModelMultipleChoiceField |
TextField | CharField with widget=forms.Textarea |
- ForeignKey is represented by django.forms.ModelChoiceField, which is a ChoiceField whose choices are a model QuerySet.
- ManyToManyField is represented by django.forms.ModelMultipleChoiceField, which is a MultipleChoiceField whose choices are a model QuerySet.
(2)、对应的属性
如果model 字段 有blank=True, 则表单类中对应的要 required=False,否则required=True
表单字段的 label 被设置为model field的 verbose_name 且第一个字符大写.
表单字段的 help_text 对应models field的 help_text
如果model 字段有choices 则表单字段widget 设置 Select
实例如下:
#coding=utf-8 from django.db import models from django import forms from django.forms import ModelForm #导入ModelForm """从一个django model中创建表单类(form model)""" TITLE_CHOICES = ( ('MR', 'Mr.'), ('MRS', 'Mrs.'), ('MS', 'Ms.'), ) class Author(models.Model): name = models.CharField(max_length=100) title = models.CharField(max_length=3, choices=TITLE_CHOICES) birth_date = models.DateField(blank=True, null=True) def __unicode__(self): return self.name class Book(models.Model): name = models.CharField(max_length=100) authors = models.ManyToManyField(Author) class AuthorForm(ModelForm): class Meta: model = Author class BookForm(ModelForm): class Meta: model = Book #以下与之对应 class AuthorForm(forms.Form): name = forms.CharField(max_length=100) title = forms.CharField(max_length=3,widget=forms.Select(choices=TITLE_CHOICES)) #choices brith_date = forms.DateField(required=False) class BookForm(forms.Form): name = forms.CharField(max_length=100) authors = forms.ModelMultipleChoiceField(queryset=Author.objects.all()) #ManyToManyField