DjangoBook笔记-4

# date: 2010-4-22
# by fatway#gmail.com

23. 表单Form类
    对于上面形式的表单,当列多时,后台需要进行繁琐的验证过程,且容易出错
    可以使用Django自带的Form类来进行表单的生成和验证

    Form类可以放置于任何地址,可以写在views.py中,但习惯上专门写进forms.py中
    
        # file:forms.py
        from django import forms
        
        class ContactForm(forms.Form):
            subject = forms.CharField()
            email = forms.EmailField(required=False)  # 可选项
            message = forms.CharField()
            
    显示表单,在shell中测试:
        >>> from forms import ContactForm
        >>> f = ContactForm()
        >>> print f
        <tr><th><label for="id_subject">Subject:</label></th><td><input type="text" name="subject" id="id_subject" /></td></tr>
        <tr><th><label for="id_email">Email:</label></th><td><input type="text" name="email" id="id_email" /></td></tr>
        <tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr>
        >>> print f['subject']
        <input type="text" name="subject" id="id_subject" />

    校验数据
        >>> f = ContactForm({'subject': 'Hello', 'email': 'adrian@example.com', 'message': 'Nice site!'})
        >>> f.is_bound  # 是否绑定form
        True
        >>> f.is_valid()  # 数据是否合法
        True
        
        >>> f = ContactForm({'subject': 'Hello', 'message': ''})
        >>> f.is_valid()  # message必填项
        False
        >>> f['message'].errors  # 查看出错信息
        [u'This field is required.']
        >>> f['subject'].errors
        []
        >>> f['email'].errors
        []
        >>> f.errors
        {'message': [u'This field is required.']}
        >>> f.cleaned_data  # 清理数据,转换成Python类型
        {message: uNice site!, email: uadrian@example.com, subject: uHello}
        


24. Form在视图中的应用
    给一个改进的示例:
        # views.py
        from django.shortcuts import render_to_response
        from mysite.contact.forms import ContactForm
        
        def contact(request):
            if request.method == 'POST':
                form = ContactForm(request.POST)
                if form.is_valid():
                    cd = form.cleaned_data
                    send_mail(
                        cd['subject'],
                        cd['message'],
                        cd.get('email', 'noreply@example.com'),
                        ['siteowner@example.com'],
                    )
                    return HttpResponseRedirect('/contact/thanks/')
            else:
                form = ContactForm()
            return render_to_response('contact_form.html', {'form': form})
        
        # contact_form.html
        <html>
        <head>
            <title>Contact us</title>
        </head>
        <body>
            <h1>Contact us</h1>
        
            {% if form.errors %}
                <p style="color: red;">
                    Please correct the error{{ form.errors|pluralize }} below.
                </p>
            {% endif %}
        
            <form action="" method="post">
                <table>
                    {{ form.as_table }}
                </table>
                <input type="submit" value="Submit">
            </form>
        </body>
        </html>

    一些改进字段显示的方法
        改进message显示方式由text改为textarea            
            class ContactForm(forms.Form):
                subject = forms.CharField()
                email = forms.EmailField(required=False)
                message = forms.CharField(**widget=forms.Textarea** )
        设置最大长度
            class ContactForm(forms.Form):
                subject = forms.CharField(**max_length=100** )
                email = forms.EmailField(required=False)
                message = forms.CharField(widget=forms.Textarea)
        指定显示标签
            class ContactForm(forms.Form):
                subject = forms.CharField(max_length=100)
                email = forms.EmailField(required=False, **label='Your e-mail address'** )
                message = forms.CharField(widget=forms.Textarea)
            
    设置初始值
        可以在view方法中创建form实体时,使用initial参数进行初始值的设定
            def contact(request):
                if request.method == 'POST':
                    form = ContactForm(request.POST)
                    if form.is_valid():
                        cd = form.cleaned_data
                        send_mail(
                            cd['subject'],
                            cd['message'],
                            cd.get('email', `'noreply@example.com`_'),
                            [`'siteowner@example.com`_'],
                        )
                        return HttpResponseRedirect('/contact/thanks/')
                else:
                    form = ContactForm(
                        **initial={'subject': 'I love your site!'}**
                    )
                return render_to_response('contact_form.html', {'form': form})


25. 自定义Form校验规则            
    在前面的form设计中,只是在数据提交后进行一些简单的校验,如果想自定义规则
    可以使用clean_**方法

    如,我们希望message字段有一个额外的检查长度的校验,可以定义clean_message()
        from django import forms
        
        class ContactForm(forms.Form):
            subject = forms.CharField(max_length=100)
            email = forms.EmailField(required=False)
            message = forms.CharField(widget=forms.Textarea)
        
            def clean_message(self):
                message = self.cleaned_data['message']
                num_words = len(message.split())
                if num_words < 4:
                    raise forms.ValidationError("Not enough words!")
                return message

    Django的form系统会自动匹配以clean_开头并以字段名结尾的函数,在校验时被调用
    在函数的末尾显式地返回字段的值非常重要
    可以在自定义的校验方法中修改它的值(或者把它转换成另一种Python类型)
    如果我们忘记了这一步,None值就会返回,原始的数据就丢失掉了


26. 定制Form设计
    在上面的模板显示中,使用{{ form.as_table }}来展示表单
    还可以更精确的控制表单显示方式
        
        使用CSS来控制
        
        重写form的显示方式
            每个字段部件<input type="text">, <select>, <textarea>等都可以 \
            通过访问 {{ from.字段名 }}进行单独的渲染

            # contact_from.html
            <html>
            <head>
                <title>Contact us</title>
            </head>
            <body>
                <h1>Contact us</h1>

                {% if form.errors %}
                    <p style="color: red;">
                        Please correct the error{{ form.errors|pluralize }} below.
                    </p>
                {% endif %}

                <form action="" method="post">
                    <div class="field">
                        {{ form.subject.errors }}
                        <label for="id_subject">Subject:</label>
                        {{ form.subject }}
                    </div>
                    <div class="field">
                        {{ form.email.errors }}
                        <label for="id_email">Your e-mail address:</label>
                        {{ form.email }}
                    </div>
                    <div class="field">
                        {{ form.message.errors }}
                        <label for="id_message">Message:</label>
                        {{ form.message }}
                    </div>
                    <input type="submit" value="Submit">
                </form>
            </body>
            </html>

            {{ form.message.errors }} 会在 <ul class="errorlist"> 里面显示,
            如果字段是合法的,或者form没有被绑定,就显示一个空字符串

            还可以对 form.message.errors 做迭代 
                <div class="field{% if form.message.errors %} errors{% endif %}">
                    {% if form.message.errors %}
                        <ul>
                        {% for error in form.message.errors %}
                            <li><strong>{{ error }}</strong></li>
                        {% endfor %}
                        </ul>
                    {% endif %}
                    <label for="id_message">Message:</label>
                    {{ form.message }}
                </div>

# 以上内容既DjangoBook该书的介绍性文章tutorial ,完成了对django的总体认识
# 已经可以本着拿来主义的精神进行实际项目的开展了
# 后面的内容会进行深入和高阶的介绍

 

-To be Continue-

posted @ 2010-04-23 10:48  听风  阅读(550)  评论(1编辑  收藏  举报