#表单-django
@(python)
- URL相关信息
HttpRequest对象包含当前请求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| - 简单例子
在users app下views.py,添加一下代码
from django.http import HttpResponse def search_form(request): return render_to_response('search_form.html') def search(request): if 'name' in request.GET: try: info = Info.objects.get(name=request.GET['name']); except Info.DoesNotExist: message = 'no query' else: message = 'You searched for: %s %s %s' % (info.name,info.sex,info.email) else: message = 'You submitted an empty form.' return HttpResponse(message)
同时新建模版文件search_form.html
<!--search_form.html--> <html> <head> <title>Search</title> </head> <body> <form action="/search/" method="get"> name:<input type="text" name="name"> <input type="submit" value="Search"> </form> </body> </html>
在urls.py添加一下规则
url(r'^search_form/$', 'users.views.search_form'), url(r'^search/$', 'users.views.search'),
打开浏览器http://ip:8000/search_form/,就会看到一下界面
- django.form
在app中新建form.py,构建表单属性,这个不一定单独构建form.py文件,可以放到任何地方,甚至写入views.py中。
#form.py #coding=utf-8 #forms.py from django import forms class UsersForm(forms.Form): name = forms.CharField(max_length=30) sex = forms.CharField(max_length=6) age = forms.IntegerField() email = forms.EmailField(required=False)
在views.py添加一下代码
from users.forms import UsersForm from django.views.decorators.csrf import csrf_exempt @csrf_exempt def show_form(request): if request.method == 'POST': form = UsersForm(request.POST) if form.is_valid(): cd = form.cleaned_data message = 'You searched for: %s %s %s' % (cd['name'],cd['sex'],cd['email']) return HttpResponse(message) #return HttpResponseRedirect('/contact/thanks/') else: form = UsersForm(initial={'email': '@'}) return render_to_response('users_form.html', {'form': form})
新建模版文件users_form.html
<html> <head> <title>Show User</title> </head> <body> <h1>Show User</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>
此时打开浏览器http://ip:8000/show_form/,会看到如下界面
如果没有添加from django.views.decorators.csrf import csrf_exempt
,与修饰符@csrf_exempt
,就会出现在post提交表单时会出现CSRF token missing or incorrect错误。开启django.middleware.csrf.CsrfViewMiddleware中间件后,在post提交表单时会出现CSRF token missing or incorrect错误。首先说明csrf中间件是django框架提供的阻止跨站伪造请求攻击(Cross Site Request Forgery)的一个实现。
form的initial参数是表单的默认值,如form = UsersForm(initial={'email': '@'})
是email的默认值是@
.
- 自定义校验规则
django可以允许自定义对提交的表单进行校验,先看看下面的例子
#coding=utf-8 #forms.py from django import forms class UsersForm(forms.Form): name = forms.CharField(max_length=30) sex = forms.CharField(max_length=6) age = forms.IntegerField() email = forms.EmailField(required=False) def clean_sex(self): sex = self.cleaned_data['sex'] if sex not in ['male','female']: raise forms.ValidationError("sex item error") return sex
Django的form系统自动寻找匹配的函数方法,该方法名称以clean_开头,并以字段名称结束。 特别地,clean_sex()方法将在指定字段的默认校验逻辑执行之后被调用。如果有这样的方法,它将在校验时被调用。例子中的clean_sex是对sex字段进行校验,使用cleaned_data提取表单值.
- 指定标签
<label>
标签为 input 元素定义标注(标记)。
label 元素不会向用户呈现任何特殊效果。不过,它为鼠标用户改进了可用性。如果您在 label 元素内点击文本,就会触发此控件。就是说,当用户选择该标签时,浏览器就会自动将焦点转到和标签相关的表单控件上。
<form> <label for="male">Male</label> <input type="radio" name="sex" id="male" /> <br /> <label for="female">Female</label> <input type="radio" name="sex" id="female" /> </form>
class UsersForm(forms.Form): name = forms.CharField(max_length=30) sex = forms.CharField(max_length=6) age = forms.IntegerField() email = forms.EmailField(required=False,label='Your e-mail address')
把该form打印出来,此时email没有添加label='Your e-mail address',
>>> from users.forms import UsersForm >>> f = UsersForm >>> print f <class 'users.forms.UsersForm'> >>> f = UsersForm() >>> print f <tr><th><label for="id_name">Name:</label></th><td><input id="id_name" maxlength="30" name="name" type="text" /></td></tr> <tr><th><label for="id_sex">Sex:</label></th><td><input id="id_sex" maxlength="6" name="sex" type="text" /></td></tr> <tr><th><label for="id_age">Age:</label></th><td><input id="id_age" name="age" type="number" /></td></tr> <tr><th><label for="id_email">Email:</label></th><td><input id="id_email" name="email" type="email" /></td></tr> >>>
添加label后,email的label变为<label for="id_email">Your e-mail address:</label>
>>> from users.forms import UsersForm >>> f = UsersForm() >>> print f <tr><th><label for="id_name">Name:</label></th><td><input id="id_name" maxlength="30" name="name" type="text" /></td></tr> <tr><th><label for="id_sex">Sex:</label></th><td><input id="id_sex" maxlength="6" name="sex" type="text" /></td></tr> <tr><th><label for="id_age">Age:</label></th><td><input id="id_age" name="age" type="number" /></td></tr> <tr><th><label for="id_email">Your e-mail address:</label></th><td><input id="id_email" name="email" type="email" /></td></tr> >>>
如果点击email项,则会显示"Your e-mail address"。
- 控制label和id
可以使用auto_id变量控制label和id ,auto_id必须为True、False或字符串。
>>> f = UsersForm(auto_id=False)#省略了id和label >>> print f <tr><th>Name:</th><td><input maxlength="30" name="name" type="text" /></td></tr> <tr><th>Sex:</th><td><input maxlength="6" name="sex" type="text" /></td></tr> <tr><th>Age:</th><td><input name="age" type="number" /></td></tr> <tr><th>Your e-mail address:</th><td><input name="email" type="email" /></td></tr> >>>
如果auto_id = True 则会自动使用label,且id名称为它们的字段名
>>> f = UsersForm(auto_id=True) >>> print f <tr><th><label for="name">Name:</label></th><td><input id="name" maxlength="30" name="name" type="text" /></td></tr> <tr><th><label for="sex">Sex:</label></th><td><input id="sex" maxlength="6" name="sex" type="text" /></td></tr> <tr><th><label for="age">Age:</label></th><td><input id="age" name="age" type="number" /></td></tr> <tr><th><label for="email">Your e-mail address:</label></th><td><input id="email" name="email" type="email" /></td></tr> >>>
auto_id使用格式化字符串(%s)
>>> f = UsersForm(auto_id='id_for_%s') >>> print f <tr><th><label for="id_for_name">Name:</label></th><td><input id="id_for_name" maxlength="30" name="name" type="text" /></td></tr> <tr><th><label for="id_for_sex">Sex:</label></th><td><input id="id_for_sex" maxlength="6" name="sex" type="text" /></td></tr> <tr><th><label for="id_for_age">Age:</label></th><td><input id="id_for_age" name="age" type="number" /></td></tr> <tr><th><label for="id_for_email">Your e-mail address:</label></th><td><input id="id_for_email" name="email" type="email" /></td></tr> >>>
通过上面我们知道,默认的auto_id使用格式化字符串 auto_id = 'id_%s'
接下来控制Label后缀,通过label_suffix 进行控制
>>> f = UsersForm(label_suffix='_form') >>> print f <tr><th><label for="id_name">Name_form</label></th><td><input id="id_name" maxlength="30" name="name" type="text" /></td></tr> <tr><th><label for="id_sex">Sex_form</label></th><td><input id="id_sex" maxlength="6" name="sex" type="text" /></td></tr> <tr><th><label for="id_age">Age_form</label></th><td><input id="id_age" name="age" type="number" /></td></tr> <tr><th><label for="id_email">Your e-mail address_form</label></th><td><input id="id_email" name="email" type="email" /></td></tr> >>>
- 自定义验证样式类
如果验证不通过,则会输出错误,对应的有“必需”、‘错误’两项,那么就在这两项中做文章。
添加一下代码,表格添加相应的css class。
error_css_class = 'error'#当提示错误的时候,使用的是error类 required_css_class = 'required'#当提示必须的时候,使用required
#coding=utf-8 #forms.py from django import forms class UsersForm(forms.Form): name = forms.CharField(max_length=30) sex = forms.CharField(max_length=6) age = forms.IntegerField() email = forms.EmailField(required=False,label='Your e-mail address') error_css_class = 'error'#当提示错误的时候,使用的是error类 required_css_class = 'required'#当提示必须的时候,使用required类 def clean_sex(self): sex = self.cleaned_data['sex'] if sex not in ['male','female']: raise forms.ValidationError("sex item error") return sex
>>> from users.forms import UsersForm >>> f = UsersForm() >>> print f <tr class="required"><th><label class="required" for="id_name">Name:</label></th><td><input id="id_name" maxlength="30" name="name" type="text" /></td></tr> <tr class="required"><th><label class="required" for="id_sex">Sex:</label></th><td><input id="id_sex" maxlength="6" name="sex" type="text" /></td></tr> <tr class="required"><th><label class="required" for="id_age">Age:</label></th><td><input id="id_age" name="age" type="number" /></td></tr> <tr><th><label for="id_email">Your e-mail address:</label></th><td><input id="id_email" name="email" type="email" /></td></tr> >>>
- 定制Form设计
虽然,自动生成HTML是很方便的,但是在某些时候,你会想覆盖默认的显示。 {{form.as_table}}和其它的方法在开发的时候是一个快捷的方式,form的显示方式也可以在form中被方便地重写。
每一个字段部件(<input type=”text”>, <select>, <textarea>
, 或者类似)都可以通过访问{{form.字段名}}进行单独的渲染。
<html> <head> <title>Show user</title> </head> <body> <h1>Show user/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.name.errors }} <label for="id_name">name:</label> {{ form.name }} </div> <div class="field"> {{ form.email.errors }} <label for="id_email">Your e-mail address:</label> {{ form.email }} </div> <div class="field"> {{ form.sex.errors }} <label for="id_sex">sex:</label> {{ form.sex }} </div> <div class="field"> {{ form.age.errors }} <label for="id_age">age:</label> {{ form.age }} </div> <input type="submit" value="Submit"> </form> </body> </html>
这样,我们就可以针对它们使用CSS。
参考文献
http://docs.30c.org/djangobook2/chapter07/
http://www.cnblogs.com/BeginMan/archive/2013/09/06/3306081.html
来源:http://www.cnblogs.com/liton/p/4245482.html