Django学习笔记(五)—— 表单

疯狂的暑假学习之  Django学习笔记(五)—— 表单

参考:《The Django Book》 第7章

1. HttpRequest对象的信息

request.path                                 除域名以外的请求路径,斜杠开头                      “/hello/”

request.get_host()                      主机名                                                                      “127.0.0.1:8000”  or “www.xxxx.com”

request.get_full_path()              请求路径,可能包含查询字符串                          “/hello/?print=true”

request.is_secure()                    是否通过Https访问                                                是为True,否为False

request.META                               一个字典,包含本次Http请求的Header信息    例如 REMOTE_ADDR 表示客户端ip,

                                                                                                                                                    HTTP_USER_AGENT表示用户浏览器user-agent字符串

                                                                                                                                                    HTTP_REFERER表示进站前连接网页 

request.POST                              一个类字典对象保存html中<form>标签提交的内容

request.GET                                 一个类字典对象保存html中<form>标签提交的内容或者URL中的查询字符串

例子:显示request.META
中的所有信息

在view.py中加入下面代码。并在urls.py加上对应的URLpattern

def test(request):
    values = request.META.items()
    values.sort()
    html = []
    for k,v in values:
        html.append('<tr><td>%s</td><td>%s</td></tr>' %  (k,v))
    return HttpResponse('<table>%s</table>' % '\n'.join(html))

2. 一个简单的表单处理

在templates中创建search_form.html模板:

<html>
<head>
    <title>Search</title>
</head>
<body>
    {% if error  %}
        <p style="color: red;">Please submit a search term.</p>
    {% endif %}
    <form action='' method='get'>
        <input type='text' name='q'>
        <input type='submit' value='Search'>
    </form>
</body>
</html>

其中action=‘‘
 表示表单将提交给与当前页面相同的URL

再添加search_results.html

<p>You searched for: <strong>{{ query }}</strong></p>

{% if books %}
<p>Found {{ books|length }} book{{ books|pluralize }}.</p>
    <ul>
        {% for book in books %}
        <li>{{ book.title }}</li>
        {% endfor %}
    </ul>
{% else %}
    <p> No books matched your search criteria. </p>
{% endif %}

在view.py中添加:

def search(request):
    error = False
    if 'q' in request.GET:
        q = request.GET['q']
        if not q:
            error = True
        else:
            books = Book.objects.filter(title__icontains=q)
            return render_to_response('search_results.html',
                    {'books':books,'query':q})
    return render_to_response('search_form.html',
            {'error':error})
    

其中Book.objects.filter(title__icontains=q) 是用来获取数据库中标题包含q的书籍。icontains是一个查询关键字。

在urls.py 中添加

  (r'search/$',search),

然后在浏览器输入
http://127.0.0.1:8000/search/  可以看到一个简单的搜索界面。

3. 简单的验证

可以用Javascript在客户端浏览器进行验证,但可能有些人会将Javascript关闭,并且还有一些怀有恶意的用户会尝试提交非法的数据来探测是否有可以攻击的机会。所以除了用Javascript在客户端浏览器进行验证外,还需要在服务器验证一次。上面的代码,只对
输入为空做了验证。下面添加一个验证搜索关键字是否小于20个字符的验证。

例子:

修改view.py

def search(request):
    errors = []
    if 'q' in request.GET:
        q = request.GET['q']
        if not q:
            errors.append('Enter a search term')
        elif len(q) > 20:
            errors.append('Please enter at most 20 characters.')
        else:
            books = Book.objects.filter(title__icontains=q)
            return render_to_response('search_results.html',
                    {'books':books,'query':q})
    return render_to_response('search_form.html',
            {'errors':errors})

修改 search_form.html :

<html>
<head>
    <title>Search</title>
</head>
<body>
    {% if errors  %}
        {% for error in errors%}
        <p style="color: red;">{{ error }}</p>
        {% endfor %}
    {% endif %}
    <form action='' method='get'>
        <input type='text' name='q'>
        <input type='submit' value='Search'>
    </form>
</body>
</html>

4. 编写Contact表单

一个较为复杂的例子:这个表单包括用户提交的反馈信息,一个可以选择填不填的e-mail地址。

view.py
中添加:

def contact(request):
    errors = []
    if request.method == 'POST':
        if not request.POST.get('subject', ''):
            errors.append('Enter a subject.')
        if not request.POST.get('message', ''):
            errors.append('Enter a message.')
        if request.POST.get('email') and '@' not in request.POST['email']:
            errors.append('Enter a valid e-mail address.')
        if not errors:
            send_mail(
                request.POST['subject'],
                request.POST['message'],
                request.POST.get('email', '[email protected]'),
                ['[email protected]'],
            )
            return HttpResponseRedirect('/contact/thanks/')
    return render_to_response('contact_form.html', {
        'errors': errors,
        'subject': request.POST.get('subject', ''),
        'message': request.POST.get('message', ''),
        'email': request.POST.get('email', ''),
    },context_instance=RequestContext(request))

用POST不用GET,因为这个表单会有一个服务器端的操作:send_mail。

在templates中添加contact_form.html

<html>
<head>
    <title>Contact us</title>
</head>
<body>
    <h1>Contact us</h1>

    {% if errors %}
        <ul>
            {% for error in errors %}
            <li>{{ error }}</li>
            {% endfor %}
        </ul>
    {% endif %}

    <form action="/contact/" method="post">
        {% csrf_token %}
        <p>Subject: <input type="text" name="subject" value="{{ subject }}"></p>
        <p>Your e-mail (optional): <input type="text" name="email" value="{{ email }}"></p>
        <p>Message: <textarea name="message" rows="10" cols="50">{{ message }}</textarea></p>
        <input type="submit" value="Submit">
    </form>
</body>
</html>

这个例子看起来杂乱,解决方法看下面用forms。

5. from类

上面的那个例子,看起来杂乱,并且容易出错。

Django带有一个form库,称为django.forms,这个库可以处理HTML表单显示以及验证。

新建
forms.py 加入

from django import forms

class ContactForm(forms.Form):
    subject = forms.CharField()
    email = forms.EmailField(required=False)
    message = forms.CharField()

很像模块中用的语法。默认是每个字段必填的,如果要是可以不填的要指定required=False,就像上面的email字段一样。

来看看forms类到底是什么:它做的第一个是就是将自己显示成HTML

>>> from contact.forms import ContactForm
>>> f = ContactForm()
>>> print f
<tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" name="subject" type="text" /></td></tr>
<tr><th><label for="id_email">Email:</label></th><td><input id="id_email" name="email" type="email" /></td></tr>
<tr><th><label for="id_message">Message:</label></th><td><input id="id_message" name="message" type="text" /></td></tr>

默认是按照
<table> 现实输出的,还可以:

>>> print f.as_ul()
<li><label for="id_subject">Subject:</label> <input id="id_subject" name="subject" type="text" /></li>
<li><label for="id_email">Email:</label> <input id="id_email" name="email" type="email" /></li>
<li><label for="id_message">Message:</label> <input id="id_message" name="message" type="text" /></li>
>>> print f.as_p()
<p><label for="id_subject">Subject:</label> <input id="id_subject" name="subject" type="text" /></p>
<p><label for="id_email">Email:</label> <input id="id_email" name="email" type="email" /></p>
<p><label for="id_message">Message:</label> <input id="id_message" name="message" type="text" /></p>

还可以这样显示

>>> print f['subject']
<input id="id_subject" name="subject" type="text" />

forms对象做的第二件事是校验数据。现在先添加数据:

>>> f = ContactForm({'subject': 'Hello', 'email': '[email protected]', 'message': 'Nice site!'})
>>> 

一旦对一个forms对象实体赋值,就可以得到一个绑定的form:

>>> f.is_bound
True
>>> 

还可以验证数据是否合法

>>> f.is_valid()
True
>>> 

如果合法为True。如果不合法为False。如:如果subject或者,essage为空。f.is_valid()就会返回False

也可以查看每个字段的error

>>> f = ContactForm({'subject': 'Hello', 'message': ''})
>>> f['message'].errors
[u'This field is required.']
>>> f['subject'].errors
[]
>>> 

还可以通过errors属性查看错误

>>> f.errors
{'message': [u'This field is required.']}
>>> 

如果forms合法,他就有一个cleaned_data属性,将数据转化成Python类型数据,存放在cleaned_data中。

例如:如果是字符串就会被清理成Unicode对象,整数会被清理成Python整数,日期清理成datetime.date型对象

>>> f = ContactForm({'subject': 'Hello', 'email': '[email protected]', 'message': 'Nice site!'})
>>> f.is_valid()
True
>>> f.cleaned_data
{'message': u'Nice site!', 'email': u'[email protected]', 'subject': u'Hello'}

6. 在视图中使用Form对象

例子:

view.py

from django.shortcuts import render
from contact.forms import ContactForm
from django.http import HttpResponseRedirect
from django.core.mail import send_mail

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', '[email protected]'),
                ['[email protected]'],
            )
            return HttpResponseRedirect('/contact/thanks/')
    else:
        form = ContactForm()
    return render(request, '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>
        {% csrf_token %}
        <input type="submit" value="Submit">
    </form>
</body>
</html>

上面的例子有个缺陷,message这个表单变成了 input type=“text”。

我们可以通过设置widget来修改它:

from django import forms

class ContactForm(forms.Form):
    subject = forms.CharField()
    email = forms.EmailField(required=False)
    message = forms.CharField(widget=forms.Textarea)

还可以设置最大长度

设置max_length

from django import forms

class ContactForm(forms.Form):
    subject = forms.CharField(max_length=20)
    email = forms.EmailField(required=False)
    message = forms.CharField(widget=forms.Textarea)

设置初始值:

在view.py中ContectForm中添加 initial 参数:

from django.shortcuts import render
from contact.forms import ContactForm
from django.http import HttpResponseRedirect
from django.core.mail import send_mail

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', '[email protected]'),
                ['[email protected]'],
            )
            return HttpResponseRedirect('/contact/thanks/')
    else:
        form = ContactForm(
            initial={'subject': 'AAAAAA'}
        )
    return render(request, 'contact_form.html', {'form': form})

注意:默认值与表单传入是有区别的,区别在于,如果仅仅传入默认值,是没有绑定的。

7. 自定义校验规则

例如我们需要添加 message 字段有一个额外的校验,我们就要摘forms类中添加 clean_message() 方法

例子:添加校验 messge中的单词数量(注意不是字母数量,看 split() )要不少于4个.

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学习笔记(五)—— 表单,布布扣,bubuko.com

时间: 2024-10-12 21:58:47

Django学习笔记(五)—— 表单的相关文章

[学习笔记]--Jfinal 表单提交附件

最近,项目里面用到了Jfinal 里面的上传附件.Jfinal 的Controller 里面提供了一个 getFile系列方法提供文件上传. 我这里呢,是文件上传和表单参数一起提交.页面类似下图: 这里form表单里面使用了 enctype="multipart/form-data" .先看看Jfinal手册的说明吧!大家看了就知道了 然后还有个问题 如果是表单提交 还不可以用ajax 提交,具体的原因呢也找到了 http://www.oschina.net/question/9410

Symfony2学习笔记之表单

对于一个Web开发者来说,处理HTML表单是一个最为普通又具挑战的任务.Symfony2集成了一个Form组件,让处理表单变的容易起来.在这一节里,我们将从基础开始创建一个复杂的表单,学习表单类库中最重要的内容. Symfony2 的Form组件是一个独立的类库,你可以在Symfony2项目之外使用它. 创建一个简单的表单:假设你要创建一个应用程序的todo列表,需要显示一些任务.因为你的用户需要编辑和创建任务,所以你需要创建一个表单.在你开始之前,首先来看通用的Task类,用来表示和存储一个单

Bootstrap学习笔记(二) 表单

在Bootstrap学习笔记(一) 排版的基础上继续学习Bootstrap的表单,编辑器及head内代码不变. 3-1 基础表单 单中常见的元素主要包括:文本输入框.下拉选择框.单选按钮.复选按钮.文本域和按钮等. 在Bootstrap框架中,通过定制了一个类名`form-control`,也就是说,如果这几个元素使用了类名"form-control",将会实现一些设计上的定制效果. 1.宽度变成了100% 2.设置了一个浅灰色(#ccc)的边框 3.具有4px的圆角 4.设置阴影效果

Bootstrap 学习笔记 之表单(4 day)

Bootstrap学习到这里,理解了为什么它是一个框架,所谓的框架,目前看来就是它本身提供了一套完整的HTML结构和样式. 我们在使用的时候,只要按照这套规则来搭建HTML结构和加上相应的样式名后就可以了. 今天学习的是表单, Bootstrap 提供了下列类型的表单布局: 垂直表单(默认) 内联表单 水平表单 需要一提的就是表单的状态: 表单控件状态 除了 :focus 状态(即,用户点击 input 或使用 tab 键聚焦到 input 上),Bootstrap 还为禁用的输入框定义了样式,

Codeigniter入门学习笔记14—表单的验证

很久很久以前学习Codeigniter的笔记记录,很随意,但都是自己记录的,希望对需要的人有所帮助. 本文使用word2013编辑并发布 Postbird | There I am , in the world more exciting! Postbird personal website : http://www.ptbird.cn 表单验证 1.add_user ????] 2.form_check() ???? 3. ? 1.加载 ????$this->load->library('f

[知了堂学习笔记]_Jquery_Validate 表单校验的使用

一.效果图: 二.JqueryValidate的好处 在做注册.或者类似以上的表单提交的时候,大家是不是都很烦那种,把数据拿到后台去判断, 可能经过了正则表达式之类的复杂判断,然后发现数据错误.接着通过request转发到页面上,再通过EL 表达式输出错误信息.实话实话,在没发现这个插件之前,我是这么干的,好痛苦的感觉. JqueryValidate的好处就在于,你不必经过servlet,就可以在页面上面判断用户输入的信息是否正确,它能够快速实现 表单的校验. 三.引入插件 顺序不能乱,此插件是

Bootstrap3学习笔记:表单

<!DOCTYPE html> <html> <head> <meta charst="gb2312"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <!-- user-scalable=no 在移动设备浏览器上,禁止用户缩放(zooming) --> <meta name="viewport&q

HTML学习笔记20——表单form (用户注册表)

表单:用户注册,在线报名……时,需要把用户的相关信息填写并提交,这时就需使用到表单来收集用户信息. 基本格式: [action 用于控制提交的地方(默认为自己的页面,也可在其值定义其他的网站名),method(默认是将信息的内容直接显示在提交的页面网址上)当设置method=”post“时就不会将信息内容全部显示到提交的页面网址上]action控制往哪里发,method控制发送方式: <form action=""    > <p>信息1</p> &

AngularJS学习笔记(二) 表单验证案例(ng-repeat/filter)

这一节相对来说需要理解的东西不是太多,记住了那些api就行了. 还是一个案例(同样来自miaov),一个表单验证,先上代码,然后再对对应的内容进行解释. <!DOCTYPE html> <html lang="en" ng-app="myApp"> <head> <meta charset="UTF-8"> <title>Title</title> </head>

JS学习笔记7_表单脚本

1.获取表单及表单元素引用的方式 var mForm = document.forms[formName];获取表单引用 mForm.elements[elemName]获取表单元素,如有同名的,则得到一组元素(例如radio button) 2.表单元素的常用属性.方法和事件 属性: name:字段名 value:字段值 type:字段类型,例如button, radio等等 readOnly:设置只读 disabled:设置禁用 方法: focus():获得焦点 blur():取消焦点 事件