Django学习笔记5--表单

Django 对用户通过表单提交的数据进行访问,有效性检查,以及其他处理.

1.从requset对象中获得数据

每个view函数的第一个参数是HttpResquest对象

def hello(request):
    return HttpResponse("Hello world")

如上, 变量request 就是一个HttpRequest 对象, 会它有自己的属性方法,在view 函数执行过程中,可以用这些属性来获取当前request的一些信息,比如加载这个页面的是是谁,或者用的是什么浏览器

 

URL相关信息

属性/方法                             说明                                                      举例

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

request.get_host()              主机名(比如,通常所说的域名)               "127.0.0.1:8000"   or  " www.example.com"

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

request.is_secure()            如果通过HTTPS访问,则此方法返回True, 否则返回False                True 或者 False

 

2.有关request的其它信息
request.META 是一个Python字典,包含了所有本次HTTP请求的Header信息,比如用户IP地址和用户Agent
(通常是浏览器的名称和版本号)。 注意,Header信息的完整列表取决于用户所发送的Header信息和服务器
端设置的Header信息。 这个字典中几个常见的键值有:

  • HTTP_REFERER ,进站前链接网页,如果有的话。 (请注意,它是 REFERRER 的笔误。)
  • HTTP_USER_AGENT ,用户浏览器的user-agent字符串,如果有的话。 例如:
    "Mozilla/5.0 (X11; U; Linux i686; fr‐FR; rv:1.8.1.17) Gecko/20080829 Firefox/2.0.0.17" .

  • REMOTE_ADDR 客户端IP,如: "12.345.67.89" 。(如果申请是经过代理服务器的话,那么它可能是以逗号分
    割的多个IP地址,如: "12.345.67.89,23.456.78.90" 。)

注意,因为 request.META 是一个普通的Python字典,因此当你试图访问一个不存在的键时,会触发一个
KeyError异常。 (HTTP header信息是由用户的浏览器所提交的、不应该给予信任的“额外”数据,因此你总
是应该好好设计你的应用以便当一个特定的Header数据不存在时,给出一个优雅的回应。)你应该用
try/except 语句,或者用Python字典的 get() 方法来处理这些“可能不存在的键”:

def ua_display_good1(request):
    try:
        ua=request.META["HTTP_USER_AGENT"]
    except KeyError:
        ua='unknow'
    return HttpResponse("Your browser is %s" %ua)

def ua_display_good2(request):
    ua=request.META.get('HTTP_USER_AGENT','unknown')
    return HttpResponse("Your browser is %s" %ua)

可以写一个函数来显示request.MEAT的所有数据,这样你就知道里面有什么了,

def display_meta(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)+"\n")
    return HttpResponse('<tables>%s</tables>'%'\n'.join((html)))

3.提交的数据信息

除了基本的元数据,HttpRequest对象还有两个属性包含了用户所提交的信息: request.GET 和 request.POST 二者都是类字典对象,你可以通过它们来访问GET和POST数据.

类字典对象: requeset.GET request.POST是类字典对象,他们的行为像Python里标准字典对象,但是在技术底层不是标准字典, 虽然他们都有get(),keys() 和 values()方法,你可以用for key in request.GET 获取所有的键,但是他们还有一些普通字典没有的方法.

Post数据是来自html的<fom>标签提交的,而get数据可能来自<from>提交也可能是url中的查询字符串

表单开发分为两部分,前端html页面用户接口和后台view函数对所提交的数据的处理过程

 ----一个表单处理示例

首先在view建立一个显示一个搜索表单:

def search_form(request):
    return render_to_response('search_form.html')

serch_form.html 

<!DOCTYPE html>
<html>
<head>
    <title>Searchheel</title>
</head>
<body>
       <form action="/search/" method="get">
           <input type="text" name="q">
           <input type="submit" value="Search">
       </form>

</body>
</html>

然后在url匹配,还有一点,就是在引用这个Temlate的时候,总是会显示TemplateDoesNotExist错误.原因是没有把html文件的目录放在settings 中,

可以在settings中添加

TEMPLATE_DIRS = (os.path.join(BASE_DIR, 'templates').replace('\\','/'),)

然后模板的目录就是,把html文件放在template文件中即可

.然后写action中 "/search/" 的views实现:

def search(request):
    if 'q' in request.GET:
        message="You searched: %r " % request.GET['q']
    else:
        message='You submitted an empty form'
    return HttpResponse(message)

那数据是如何在这个系统中传递的呢?

  1. 首先我们在html中定义了一个q,当提交表单的时候,变量q的值通过GET(metho="get") 附加在URL/search/上
  2. 处理/search/的视图,通过request.GET 来获取q的值
  3. 需要注意的是这里需要判断q是否在GET中,对于用户提交过来的数据要进行过滤,和检查,否则会有异常,如这可能会有keyError
  4. 我还想知道GET传递了什么内容

 

 

5,HttpResponseRedirect对象将网页重定向至一个包含成功信息的页面, 若一个用户刷新一个包含post表单的页面,那么请求将会重新发生找成重复, 如果在post表单之后重定向到另外的网页就不会造成重复请求, 所以不是直接 reder_to_response() ,我们应该为每次成功的post请求做重定向

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','noreply@example.com'),
                ['siteowner@example.com'],
            )
            return HttpResponseRedirect('/contact/thanks')
    return render_to_response('contact_form.html',{'errors':errors})

6.高级库的用意--- 处理表单和相关校验任务

  1. 第一个Form类: 处理html 表单显示以及验证( Django的 newform)
  2. 表单框架主要用法,为每个要处理的html的"<Form>"定义为一个Form类,这个Form类可以放在任意地方,但也习惯性放在 form.py目录
__author__ = 'peggy'
from django import forms

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

        表单中每个字段(域)作为form类的属性,被展现为Field类,表单在python解释器里面,把自己显示成为html

        Form 对象做的第二件事是校验数据。 为了校验数据,我们创建一个新的对 Form 象,并且传入一个与定义匹配的

  • 字典类型数据:
    >>> f = ContactForm({'subject': 'Hello', 'email': 'adrian@example.com', 'message': 'Nice site!'})
    一旦你对一个 Form 实体赋值,你就得到了一个绑定form:
    >>> f.is_bound
    True
    调用任何绑定form的 is_valid() 方法,就可以知道它的数据是否合法。 我们已经为每个字段传入了值,因此整
    个 Form 是合法的:
    >>> f.is_valid()
    True
    如果我们不传入 email 值,它依然是合法的。因为我们指定这个字段的属性 required=False :
    >>> f = ContactForm({'subject': 'Hello', 'message': 'Nice site!'})
    >>> f.is_valid()
    True
    但是,如果留空 subject 或 message ,整个 Form 就不再合法了:
    >>> f = ContactForm({'subject': 'Hello'})
    >>> f.is_valid()
    False
    >>> f = ContactForm({'subject': 'Hello', 'message': ''})
    >>> f.is_valid()
    False
    你可以逐一查看每个字段的出错消息:
    >>> f = ContactForm({'subject': 'Hello', 'message': ''})
    >>> f['message'].errors
    [u'This field is required.']
    >>> f['subject'].errors
    []
    >>> f['email'].errors
    []
    1
    每一个邦定 Form 实体都有一个 errors 属性,它为你提供了一个字段与错误消息相映射的字典表。
    >>> f = ContactForm({'subject': 'Hello', 'message': ''})
    >>> f.errors
    {'message': [u'This field is required.']}
    最终,如果一个 Form 实体的数据是合法的,它就会有一个可用的 cleaned_data 属性。 这是一个包含干净的提交
    数据的字典。 Django的form框架不但校验数据,它还会把它们转换成相应的Python类型数据,这叫做清理数
    据。
    >>> f = ContactForm({subject': Hello, email: adrian@example.com, message: Nice site!})
    >>> f.is_valid()
    True
    >>> f.cleaned_data
    {message': uNice site!, email: uadrian@example.com, subject: uHello}
    我们的contact form只涉及字符串类型,它们会被清理成Unicode对象。如果我们使用整数型或日期型,form
    框架会确保方法使用合适的Python整数型或 datetime.date 型对象。

 

表单form框架处理HTML显示,数据校验,数据清理和表单错误重现

  1.  改变字段显示 :    通过 widget来修改           message=forms.CharField(widget=forms.Textarea)
  2. 设置最大长度 :     subject=forms.CharField(max_length=100)
  3. 设置初始值:   创建Form实体的时候,使用initial参数:
  4. form=ContactForm( 
              initial={'subject':I love your site}
              )

     

  5. 自定义校验规则
  6. 指定标签
  7. 定制Form设计
posted @ 2015-02-02 15:58  zzblee苦瓜  阅读(230)  评论(0编辑  收藏  举报