【django 学习笔记】06-表单

URL 相关信息

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

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

request.get_full_path() 请求路径, 可能包含查 询字符串

eg.request.is_secure() “/hello/?print=true”

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

有关request 的 其它信息

  • 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″ )

# GOOD (VERSION 1)

def ua_display_good1(request):

try:

ua = request.META['HTTP_USER_AGENT']

except KeyError:

ua = ‘unknown’

return HttpResponse(“Your browser is %s” % ua)

# GOOD (VERSION 2)

def ua_display_good2(request):

ua = request.META.get(‘HTTP_USER_AGENT’, ‘unknown’)

return HttpResponse(“Your browser is %s” % ua)

提交的数据信息

request.GET request.POST 。二者都是类字典对象, 你可以通过它们来访问GETPOST 数据。

def search(request):

if ‘q’ in request.GET:

message = ‘You searched for: %r’ % request.GET['q']

else:

message = ‘You submitted an empty form.’

return HttpResponse(message)

通过数据库进行查询

from django.http import HttpResponse

from django.shortcuts import render_to_response

from mysite.books.models import Book

def search(request):

if ‘q’ in request.GET and request.GET['q']:

q = request.GET['q']

books = Book.objects.filter(title__icontains=q)

return render_to_response(’search_results.html’, {‘books’: books, ‘query’: q})

else:

return HttpResponse(‘Please submit a search term.’)

返回到模板中

<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 %}

简单的验证

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** })

<html>

<head>

<title>Search</title>

</head>

<body>

**{% if errors %}**

**<ul>**

**{% for error in errors %}**

**<li>{{ error }}</li>**

**{% endfor %}**

**</ul>**

**{% endif %}**

<form action=”/search/” method=”get”>

<input type=”text” name=”q”>

<input type=”submit” value=”Search”>

</form>

</body>

</html>

第一个Form

Django 带有一个form, 称为django.forms, 这个库可以处理我们本章 所提到的包括HTML 表单显示以及验 证。 接下来我们来深入了解一下form, 并使用她来重写contact 表单应用。

forms.py 。在存放“ views.py“ 的目录中, 创建这个文件, 然后输入:

from django import forms

class ContactForm(forms.Form):

subject = forms.CharField()

email = forms.EmailField(required=False)

message = forms.CharField()

这看上去简单易懂, 并且很像在模 块中使用的语法。 表单中的每一个字段() 作为Form 类的属性, 被展现成Field 类。这里只用到CharFieldEmailField 类型。 每一个字段都默认是必填。要使email 成 为可选项, 我们需要指定required=False

让我们钻研到Python 解释器 里面看看这个类做了些什么。 它做的第一件事是将自己显示成HTML:

>>> from contact.forms import ContactForm

>>> f = ContactForm()

>>> print f

<tr><th><label for=”id_subject”>Subject:</label></th><td><input type=”text” name=”subject” id=”id_

<tr><th><label for=”id_email”>Email:</label></th><td><input type=”text” name=”email” id=”id_email”

<tr><th><label for=”id_message”>Message:</label></th><td><input type=”text” name=”message” id=”id_

为了便于访问,Django“ <label>“ 标志, 为每一个字段添加了标签。 这个做法使默认行为尽可能合适。

默认输出按照HTML<“ table“ > 格式, 另外有一些其它格式的输出:

>>> print f.as_ul()

<li><label for=”id_subject”>Subject:</label> <input type=”text” name=”subject” id=”id_subject” /><

<li><label for=”id_email”>Email:</label> <input type=”text” name=”email” id=”id_email” /></li>

<li><label for=”id_message”>Message:</label> <input type=”text” name=”message” id=”id_message” /><

>>> print f.as_p()

<p><label for=”id_subject”>Subject:</label> <input type=”text” name=”subject” id=”id_subject” /></

<p><label for=”id_email”>Email:</label> <input type=”text” name=”email” id=”id_email” /></p>

<p><label for=”id_message”>Message:</label> <input type=”text” name=”message” id=”id_message” /></

请注意, 标签<table><ul><form> 的开闭合标记没有包含于输 出当中, 这样你就可以添加额外的行或者 自定义格式。

这些类方法只是一般情况下用于快捷显示完整表单的方法。 你同样可以用HTML 显示个别字段:

>>> print f['subject']

<input type=”text” name=”subject” id=”id_subject” />

>>> print f['message']

<input type=”text” name=”message” id=”id_message” />

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

>>> f = ContactForm({’subject’: ‘Hello’, ‘email’: ‘adrian@example.com’, ‘message’: ‘Nice site!’})

一旦你对一个Form 实体赋值, 你就得到了一个绑定form:

>>> f.is_bound

True

调用任何绑定formis_valid() 方法, 就可以知道它的数据是否合法。 我们已经为每个字段传入了值, 因此整个Form 是合法的:

>>> f.is_valid()

True

如果我们不传入email, 它依然是合法的。因为我们指定这个字段的属性required=False:

>>> f = ContactForm({’subject’: ‘Hello’, ‘message’: ‘Nice site!’})

>>> f.is_valid()

True

但是, 如果留空subjectmessage , 整个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

[]

每一个邦定Form 实体都有一 个errors 属性, 它为你提供了一个字段与错误消息相映射的字典表。

>>> f = ContactForm({’subject’: ‘Hello’, ‘message’: ”})

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

最终, 如果一个Form 实体的数据是合法的, 它就会有一个可用的cleaned_data 属性。 这是一个包含干净的提交数据的字典。 Djangoform 框架不但校验数据, 它还会把它们转换成相应的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 对 象

# 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 字段 被显示成“ input type=”text”“ , 而 它应该被显示成<“ textarea“ > 。我们可以通过设置* widget* 来修改它:

from django import forms

class ContactForm(forms.Form):

subject = forms.CharField()

email = forms.EmailField(required=False)

message = forms.CharField(**widget=forms.Textarea** )

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

设置最大长度

一个最经常使用的校验要求是检 查字段长度。 另外, 我们应该改进ContactForm, 使subject 限制在100 个字符

以内。 为此, 仅需为CharField 提供max_length 参数, 像这样:

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)

选项min_length 参数 同样可用。

设置初始值

让我们再改进一下这个表单: 为字subject 段添加* 初始值* : “I love your site!” ( 一 点建议, 但没坏

处。) 为此, 我们可以在创建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})

自定义校验规则

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

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

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

指定标签

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

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)

定制Form 设计

修改form 的显示的最快捷的方 式是使用CSS 。 尤其是错误列表, 可以增强视觉效果。自动生成的错误列表精

确的使用“ <ul class=”errorlist”>“, 这样, 我们就可以针对它们使用CSS 。 下面的CSS 让错误更加醒目

:

<style type=”text/css”>

ul.errorlist {

margin: 0;

padding: 0;

}

.errorlist li {

background-color: red;

color: white;

display: block;

font-size: 10px;

margin: 0 0 3px;

padding: 4px 5px;

}

</style>

每一个字段部件(<input type=”text”>, <select>, <textarea>, 或者类似) 都可以通过访问{{form. 字段名}} 进行单独的渲染。

<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 当作一个布尔值或者当它是list 在 上面做迭代, 例如:

<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>

在校验失败的情况下, 这段代码 会在包含错误字段的divclass 属性中增加一个”errors”, 在一个有序列表中显示错误信息。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值