一、HttpRequest对象的一些属性或方法

  • request.path,The full path, not including the domain but including the leading slash,例如:"/hello/"
  • request.get_host(),The host (i.e., the “domain,” in common parlance).例如:"127.0.0.1:8000" or"www.example.com"
  • request.get_full_path(),The path, plus a query string (if available),例如:"/hello/?print=true"
  • request.is_secure(),True if the request was made via HTTPS. Otherwise, False。例如:True or False

关于请求的其他信息request.META是一个字典,包含了所有HTTP头部信息,一些常见的keys如下:

  • HTTP_REFERER – The referring URL, if any. (Note the misspelling of REFERER.)
  • HTTP_USER_AGENT – The user’s browser’s user-agent string, if any. This looks something like:"Mozilla/5.0 (X11; U; Linux i686; fr-FR; rv:1.8.1.17) Gecko/20080829 Firefox/2.0.0.17".
  • REMOTE_ADDR – The IP address of the client, e.g., "12.345.67.89". (If the request has passed through any proxies, then this might be a comma-separated list of IP addresses, e.g., "12.345.67.89,23.456.78.90".)

注意:当不知道字典中是否含有一个键时,最好用get方法,因为META是一个字典,获取一个不存在的键会返回一个异常。例如:

ua = request.META.get('HTTP_USER_AGENT', 'unknown')

request.GET和request.POST是两个类似于字典的对象,他们都有get()keys() and values() 方法,也可以迭代for key in request.GET,

POST数据基本上是都是来自于表单提交的数据,GET可以是表单也可以是网页的URL

2、根据学生ID搜索学生信息的简单例子:

models是

class StudentInfo(models.Model):

    name = models.CharField(max_length = ,default="");
studentID = models.CharField(max_length=,default="");
sex = models.CharField(max_length = ,default="");
age = models.IntegerField(default=);
address = models.TextField(default="");

template文件夹里存放template文件,searchBase.html文件如下:

<!DOCTYPE html>
<html>
<head>
<title>
{% block title %}{% endblock %}
</title>
</head> <body>
<div>
{% block search %} {% endblock %}
</div>
<hr/>
<div>
{% block footer %}
<p>©&nbsp;Allen&nbsp;</p>
{% endblock %}
</div>
</body>
</html>

searchStudentInfo.html文件内容如下:

 {% extends "searchBase.html" %}

 {% block title %}get student infomation{% endblock %}

 {% block search %}
<h1 style="text-align:center;">根据ID搜索学生信息</h1>
<div>
<form action="/student/search/" method="post" style="text-align:center;">
<input type="text" name="q">
<input type="submit" value="搜索">
</form>
</div>
{% endblock %}

在视图文件中定义搜索id的视图,SearchForm函数

 def SearchForm(request):
return render(request, "searchStudentInfo.html")

在urls文件中定义路由

url(r'^searchform/$', views.SearchForm),

此时还不能正常工作,因为没有写搜索的响应函数。当然可以看一下效果

接下来为其添加响应函数,views.py

 def SearchStudentInfo(request):
if 'q' in request.POST:
searchInfo = "you searched %s"%request.POST['q'];
else:
searchInfo = "you submitted an empty form"
return HttpResponse(searchInfo);

添加路由

url(r'^search/$', views.SearchStudentInfo),

此时可以正常工作。

3、将查询结果做成模版进行显示

创建显示结果模版searchResult.html代码如下:

 {% extends "searchBase.html"%}

 {% block title %}search result{% endblock %}

 {% block search %}
<p>You searched for: <strong>{{ query }}</strong></p>
{% if students %}
<p>Found {{students|length}} students</p>
<table>
<tr>
<td>姓名</td>
<td>学号</td>
<td>性别</td>
<td>年龄</td>
<td>地址</td>
</tr>
{% for student in students %}
<tr> <td>{{ student.name }}</td>
<td>{{ student.studentID }}</td>
<td>{{ student.sex }}</td>
<td>{{ student.age }}</td>
<td>{{ student.address }}</td> </tr>
{% endfor %}
</table>
{% else %}
<p>not found student where studentID = {{ query }}</p>
{% endif %}
{% endblock %}

修改视图函数views.py

 def SearchStudentInfo(request):
if 'q' in request.GET and request.GET['q']:
stu = StudentInfo.objects.filter(studentID=request.GET['q'])
if stu:
context = {'query':request.GET['q'],'students':stu}
return render(request, 'searchResult.html', context)
else:
return HttpResponse("not found information"); else:
searchInfo = "you submitted an empty form"
return HttpResponse(searchInfo);

此时可以运行一下查看结果,效果如下:

二、对这个表单进行改进

对网址http://127.0.0.1:8888/student/search/进行访问,有三种可能情况

  • 访问页面,此时没有‘q’参数在GET中
  • 点击提交按钮,‘q’在GET中,但是搜索框中没有搜索内容。
  • 点击提交按钮,‘q’在GET中,搜索框中有搜索内容。

对于第一种情况我们不应该显示出错误信息,第二种情况应该显示出错信息,第三种情况应当进入数据库进行查询。为了更专业一点,当没有输入数据提交时,应当返回上一个查询框,而不是返回一个字符串。

需要修改的地方有 1、视图函数  2、在搜索模版中加入判断的变量error

views.py

 def SearchStudentInfo(request):
error = False;
if 'q' in request.GET :
if not request.GET['q']:
error=True;
else:
stu = StudentInfo.objects.filter(studentID=request.GET['q'])
context = {'query':request.GET['q'],'students':stu}
return render(request, 'searchResult.html', context) return render(request, 'searchStudentInfo.html', {'error':error});

searchStudentInfo.html

 {% extends "searchBase.html" %}

 {% block title %}search student infomation{% endblock %}

 {% block search %}
<h1 style="text-align:center;">根据ID搜索学生信息</h1>
<div>
{% if error %}
<p style="color: red;">Please submit a search term.</p>
{% endif %}
<form action="/student/search/" method="get" style="text-align:center;">
学号:<input type="text" name="q">
<input type="submit" value="搜索">
</form>
</div>
{% endblock %}

2、

<form action="" method="get">
当 action=""表示提交表单时,将向当前的url提交。

3、当表单是通过post提交过后,最好在处理过提交上来的数据后使用HttpResponseRedirect,以防止产生一些麻烦,比如:多次提交、刷新提交。可能会在后台数据库中产生多个相同记录。

from django.http import HttpResponseRedirect

三、form类,是django带来的处理form的一些类库,可以放在任意位置,不过一般将其单独成一个文件forms.py,和views.py放在同一个文件夹

首先写一个forms.py文件,ContactForm类。

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

注意:默认情况下form类的数据是必须的,可以通过参数来修改。required=False

form类对象含有一些方法,比如:as_ul(),将每项数据li列出来,as_p():将每项数据生成段落。

from studentInfo.forms import ContactForm
c=ContactForm()
print c.as_ul()
<li><label for="id_subject">Subject:</label> <input type="text" name="subject" id="id_subject" /></li>
<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" /></li>
>>> print c.as_p()
<p><label for="id_subject">Subject:</label> <input type="text" name="subject" id="id_subject" /></p>
<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" /></p>

也可以显示某一列

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

2、检查有效性,通过一个字典将forms类初始化。对象一旦初始化数据后,就是一个“bound”form。

f = ContactForm({'subject': 'Hello', 'email': 'adrian@example.com', 'message': 'Nice site!'})
f.is_bound
True

检查有效性的函数是is_valid().如果数据有效,可以通过clean()方法,返回一个没有错误的数据字典。

>>> f = ContactForm({'subject': 'Hello', 'message': 'Nice site!'})
>>> f.is_valid()
True
>>> f = ContactForm({'subject': 'Hello', 'message': ''})
>>> f.is_valid()
False

也可以获得指定域的错误信息,通过errors属性。如果有错,则会显示出来;如果没有,则是一个空的列表。

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

每一个绑定数据的对象都有一个errors属性,是一个将域和错误信息列表映射起来。

如果form对象的数据是有效的,则可以使用cleaned_data属性。他会将form对象转换成合适的python数据类型

>>> f = ContactForm({'subject': 'Hello', 'email': 'adrian@example.com', 'message': 'Nice site!'})
>>> f.is_valid()
True
>>> f.cleaned_data
{'message': u'Nice site!', 'email': u'adrian@example.com', 'subject': u'Hello'}
3、在views文件中使用forms对象,例子如下:
def ContactUs(request):
if request.method =="POST":
form = ContactForm(request.POST)
if form.is_valid():
cd = form.cleaned_data;
print cd['subject'],cd['message'],cd.get('email', 'noreply@example.com')
return HttpResponseRedirect('/student/contact/thanks/') else:
form = ContactForm(); return render(request, "contactus.html", {'form':form})

contactus.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">
{% csrf_token %}
</form>
</body>
</html>

运行结果

现在message输入框形式本应该是textarea形式,却是text line形式,可以通过修改forms类的参数来改变展现形式。

forms.py文件

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

field类表示有效逻辑,widget表示展现形式。max_length表示可以输入的最大字符数,min_length表示最少字符数。限定charfield。

4、定制forms规则,当需要一个特别的有效性规则、并且需要经常使用,可以考虑定制一个规则。在forms类中实现方法

比如不能使message输入的单词数少于4个,可以在类中写一个方法

class ContactForm(forms.Form):
subject = forms.CharField(max_length=);
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 < :
raise forms.ValidationError("Not enough words!")
return message

注意:它是以clean_开头,以字段名称结束的方法,他将在校验时调用。

我们需要在最后将校验的字段返回,否则None将会被返回,原始数据丢失。

5、指定标签

HTML表单中自动生成的标签默认是按照规则生成的:用空格代替下划线,首字母大写。如email的标签是"Email"。可以使用

label='Your e-mail address'例如:email = forms.EmailField(required=False, label='Your e-mail address' )

6、定制form设计

为了更加精确的控制显示效果,我们可以通过{{form.字段名}}进行单独的渲染

三、表单的一些高级用法
1 表单继承
Form的子类还可以被继承,也可以多重继承,如果有些变量不想在子类中使用,可以使用Meta类中的fields或exclude来限制可用变量
class Person(forms.Form):
first =forms.CharField()
last = forms.CharField()
middle = forms.CharField() class AgedPerson(Person):
age = forms.IntegerField()
class Meta:
exclude=('middle',)

2 填写表单

用request.POST来填充表单时,如果含有额外数据,form类会自动无视那些和他们定义的变量没关系的输入。

												

django1.8forms读书笔记的更多相关文章

  1. django1.6读书笔记一

    reporter是Article中的一个外键,我们可以有多篇文章指向同一个reporter,然后通过使用article_set.all()就可以返回其所有的headline了,也可以添加条件来筛选. ...

  2. django1.8读书笔记模型高级进阶

    一.访问外键和多对多值 例如:模型类定义如下 from django.db import models class Publisher(models.Model): name = models.Cha ...

  3. django1.8读书笔记模版高级进阶

    一.概述 想要定制或者扩展模版引擎,模版系统工作原理,自动转移特征 名词解析:模板 渲染 就是是通过从context获取值来替换模板中变量并执行所有的模板标签. 二.Context处理器 如果在模版中 ...

  4. 《玩转Django2.0》读书笔记-Django建站基础

    <玩转Django2.0>读书笔记-Django建站基础 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.网站的定义及组成 网站(Website)是指在因特网上根据一 ...

  5. 读书笔记汇总 - SQL必知必会(第4版)

    本系列记录并分享学习SQL的过程,主要内容为SQL的基础概念及练习过程. 书目信息 中文名:<SQL必知必会(第4版)> 英文名:<Sams Teach Yourself SQL i ...

  6. 读书笔记--SQL必知必会18--视图

    读书笔记--SQL必知必会18--视图 18.1 视图 视图是虚拟的表,只包含使用时动态检索数据的查询. 也就是说作为视图,它不包含任何列和数据,包含的是一个查询. 18.1.1 为什么使用视图 重用 ...

  7. 《C#本质论》读书笔记(18)多线程处理

    .NET Framework 4.0 看(本质论第3版) .NET Framework 4.5 看(本质论第4版) .NET 4.0为多线程引入了两组新API:TPL(Task Parallel Li ...

  8. C#温故知新:《C#图解教程》读书笔记系列

    一.此书到底何方神圣? 本书是广受赞誉C#图解教程的最新版本.作者在本书中创造了一种全新的可视化叙述方式,以图文并茂的形式.朴实简洁的文字,并辅之以大量表格和代码示例,全面.直观地阐述了C#语言的各种 ...

  9. C#刨根究底:《你必须知道的.NET》读书笔记系列

    一.此书到底何方神圣? <你必须知道的.NET>来自于微软MVP—王涛(网名:AnyTao,博客园大牛之一,其博客地址为:http://anytao.cnblogs.com/)的最新技术心 ...

随机推荐

  1. PasswordlessAPI

    passwordlessapiYOURLS允许API调用的老式的方法,使用用户名和密码参数(如果你的设置是私人的,很明显).如果担心将证书发送到野外,还可以使用秘密签名令牌进行API调用.签名的令牌你 ...

  2. Foreda8上安装Ant1.9.2

    Ant在Win上安装很简单,解压拷贝+设置Ant_Home,在Linux上差不多也是这两步. 首先下载apache-ant-1.9.2-bin.tar.gz. 然后解压tar xvzf apache- ...

  3. Android面试总结经

    自上周怒辞职以后,就開始苦逼的各种面试生涯,生活全然靠私活来接济,时有时没有,真难.还能快乐的玩耍吗.最多一天面试了5家,哎感觉都是不急招人,各种等待通知.好不easy等来一家.还克扣了薪资,从我要的 ...

  4. JDBC一(web基础学习笔记七)

    一.JDBC Java数据库的连接技术(Java DataBase Connectivity),能实现Java程序以各种数据库的访问 由一组使用Java语言编写的类和接口(JDBC API)组成,它j ...

  5. 在 Java SE 6 中监视和诊断性能问题

    Java™ Platform, Standard Edition 6 (Java SE) 专注于提升性能,提供的增强工具可以管理和监视应用程序以及诊断常见的问题.本文将介绍 Java SE 平台中监视 ...

  6. webpack 生命周期

    1.插件 可以安装lifecycle-webpack-plugin 插件来查看生命周期信息. 2.webpack流程(生命周期图) 地址:https://img.alicdn.com/tps/TB1G ...

  7. CSS nth-child、first-child、last-child、nth-of-type、first-of-type和last-of-type选择器使用

    以下示例主要讲解nth-child.first-child.last-child.nth-of-type.first-of-type和last-of-type使用. 示例代码: <!DOCTYP ...

  8. Java典型应用彻查1000例:图形与网络游戏开发 PDF 扫描版[68M]

    <Java典型应用彻查1000例·图形与网络游戏开发>实例丰富,编排合理,可以让有初级Java基础的读者,从陌生到完全熟练地设计网络游戏,进而掌握3D立体绘图方法,适合作为Java网络游戏 ...

  9. 14、Java中用浮点型数据Float和Double进行精确计算时的精度问题

    一.浮点计算中发生精度丢失 大概很多有编程经验的朋友都对这个问题不陌生了:无论你使用的是什么编程语言,在使用浮点型数据进行精确计算时,你都有可能遇到计算结果出错的情况.来看下面的例子. // 这是一个 ...

  10. spring aop的两种写法aspect和advisor

    本文转自:https://www.cnblogs.com/leiOOlei/p/3709607.html 首先看个例子,如下 接口代码: package com.lei.demo.aop.schema ...