第七章 表单

对标题的评论会显示在这里

从Google的简朴的单个搜索框,到常见的Blog评论提交表单,再到复杂的自定义数据输入接口,HTML表单一直是交互性网站的支柱。 本章介绍如何用Django对用户通过表单提交的数据进行访问、有效性检查以及其它处理。 与此同时,我们将介绍HttpRequest对象和Form对象。

对这一段的评论会显示在这里

从Request对象中获取数据

对这一段的评论会显示在这里

我们在第三章讲述View的函数时已经介绍过HttpRequest对象了,但当时并没有讲太多。 让我们回忆下:每个view函数的第一个参数是一个HttpRequest对象,就像下面这个hello()函数:

��� 10-21 17:48

���ͳeʡ���������������˴��ѣ��ٷ�ȫ�Ϊͳeʡ�����̨,ͳeʡΪ���ʵ�ͳͳ��ʡ������������Ҷ����ѣ���������һЩ��ѹ�λ������ң������ʡ�����ͳeʡ,�Ϸ��eʡ,���ͳeʡ,���ͳeʡ,���eʡ,�����eʡ,���ͳeʡ,���ͳeʡ,��ͳeʡ,��ͳeʡ,��ݸͳeʡ,���ͳeʡ, �ɶ�ͳeʡ http://www.tongesheng.com ���ͳeʡ��--��ͳeʡ 2160

yonglin 11-16 07:42

上面一条评论显示有问题

yang 05-18 06:39

为啥会出现乱码?

Sebastian 01-24 09:36

HttpRequest类是定义在django.http包的__init__.py模块中,也就是说,初始化django时,或说引入http这个模块时就会把HttpRequest初始化。

Paco 05-16 08:38

”第X章“的X中,有的是中国数字,有的是阿拉伯数组,最好统一一下。

hehe 08-21 06:40

HttpResponse明明是类,怎么说成对象了

hello 11-02 18:07

”HttpRequest对象“这种说法并没有错,可以理解为基于HttpRequest类生成的对象,比如。

Junco 06-13 12:42

语言问题了。。“HttpResponse的对象”,“的”可省略

WN 03-01 08:44

原文就是HttpRequest objects,翻译没错

对这一段的评论会显示在这里
from django.http import HttpResponse

def hello(request):
    return HttpResponse("Hello world")
对这一段的评论会显示在这里

HttpRequest对象,比如上面代码里的request变量,会有一些有趣的、你必须让自己熟悉的属性和方法,以便知道能拿它们来做些什么。 在view函数的执行过程中,你可以用这些属性来获取当前request的一些信息(比如,你正在加载这个页面的用户是谁,或者用的是什么浏览器)。

wzdxt 07-16 04:24

你必须让自己熟悉"的"属性和方法?

leo 12-07 12:18

你必须让自己熟悉"的"属性和方法?-->>你必须熟悉的属性和方法,

danpy5 08-14 06:40

你必须让自己熟悉这些属性和方法

Ignora 01-28 01:40

这句话没有什么语法问题,何必强行指正

对这一段的评论会显示在这里

URL相关信息

对这一段的评论会显示在这里

HttpRequest对象包含当前请求URL的一些信息:

vic 03-07 07:56

对这一段的评论会显示在这里

在view函数里,要始终用这个属性或方法来得到URL,而不要手动输入。 这会使得代码更加灵活,以便在其它地方重用。 下面是一个简单的例子:

һ������ 10-20 20:48

һ�����������tp://www.17hezu.com���������������˺����ѡ�����ѱ��� �Ӫҵ������˫�˫IP ������⣨�ɷ��˵վwap��վ�ȣ����˫�˫IP ����ܽ�������VIP�����ܣ��ɷ��˵վ wap ��վ�ȣ�����BGP�·����������ǿ3.6 4G���siӲ� sataӲ��ķ����� �������������������Q:86361102.���ͷ�QQ�� 61769162 61769163 61769164 61769165 ����ϵ:13811510185(�ʱΪ����)һ�����������

scarl 07-27 02:08

这广告……

brad 03-21 02:13

恩。理念问题。 国外新闻自由。IT:评论也做成不用审核。 国内还是必须审核啊。林子大。

Xavier 07-20 03:01

一楼乱码

hehe 08-21 06:21

国外新闻自由真是笑死我了,美国密苏里州圣路易斯市国际机场到弗格森镇因警察枪杀黑人男青年一事陷入混乱之中,有几个自由的新闻跟踪报道了?

hehe 08-21 06:23

再说,你什么时候发评论还得等半小时审核了?逗逼

nemo 02-13 06:07

哈哈 楼上这打脸打的狠啊

test 11-24 07:10

test

test 06-22 12:02

@hehe 你懂个屁的新闻自由?新闻自由是指没有公权力的非法审查,而且如果你说的那件事没有媒体报道,你又怎么知道的?你妈被黑人轮了之后告诉你的?

lvhua 11-15 01:53

看一下全部的返回值:def current_url_view_good(request): return HttpResponse("Welcome to the page at %s, %s, %s, %s " % (request.path,request.get_host(),request.get_full_path(),request.is_secure()))

对这一段的评论会显示在这里
# BAD!
def current_url_view_bad(request):
    return HttpResponse("Welcome to the page at /current/")

# GOOD
def current_url_view_good(request):
    return HttpResponse("Welcome to the page at %s" % request.path)
对这一段的评论会显示在这里

有关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" 。)
venj 12-25 03:02

请注意,它是REFERER的笔误。 --> 请注意,REFERER是一个笔误。 p.s. 正确的拼写是REFERRER。

viperasi 06-30 16:19

谁都会有笔误的,呵呵

tomas 11-22 08:52

IP地址怎么可能有345? 还是改成 123.45.67.89 好一点

yue 12-14 02:24

“申请” 是不是该改为 “请求”??

ULTra 01-08 04:40

看到这里发现好多的错误,而且很多都是10年前就发现了,但是作者一直没改。。我搞定Django之后一定自己重新写个这个网站。。最新版。。支持不?

jason 02-27 13:05

囧,外国也有通假字啊!!!

dkjiaoyang 04-12 00:23

支持@ULTra。

Chris 06-22 13:37

支持ULTra !!!!

lincy 08-17 00:49

@ULTra,果断支持,说话算话哈

IceWater 10-17 09:14

ULTra 搞定Django了吗? (╯▽╰)

Harry 12-05 01:17

@ULTra ,果断支持你! 现在2013年12月份了,搞定Django了没?

千里山南 01-04 14:26

原来这帮家伙也知错不改

匿名读者 02-18 16:13

@ULTra ,果断支持你! 现在2014年2月份了,搞定Django了没?

匿名读者 03-13 11:53

@ULTra ,果断支持你! 现在2014年3月份了,搞定Django了没?

匿名读者 04-09 09:52

@ULTra ,果断支持你! 现在2014年4月份了,搞定Django了没?

channingchen 05-22 06:21

@ULTra ,果断支持你! 现在2014年5月份了,搞定Django了没?

匿名读者 05-22 08:27

@ULTra ,果断支持你! 现在2014年5月22日16:27:53了,搞定Django了没?

Adamee@foxmail.com 05-22 08:28

@ULTra ,果断支持你! 现在2014年5月22日16:27:53了,搞定Django了没? 终于看见最新的活人了

tzy 06-09 11:52

@ULTra ,果断支持你! 现在2014年6月9日了,搞定Django了没?

gangboy 06-12 06:40

@ULTra ,果断支持你! 现在2014年6月12日了,搞定Django了没?

xon 06-30 13:14

@ULTra ,果断支持你! 现在2014年6月30日了,搞定Django了没?

jack 07-03 13:20

@ULTra ,果断支持你! 现在2014年7月3日了,搞定Django了没?

戳戳龙 07-19 06:54

@ULTra 好人一生平安

Xavier 07-20 03:06

@ULTra ,果断支持你! 现在2014年7月20日了,搞定Django了没?

estar7 08-04 07:12

@ULTra ,果断支持你! 现在2014年7月20日了,搞定Django了没?

estar7 08-04 07:13

@ULTra ,果断支持你! 现在2014年8月4日了,搞定Django了没?

mihello 08-08 13:54

@ULTra ,果断支持你! 现在2014年8月8日了,搞定Django了没?

nilin214 08-24 06:55

@ULTra ,果断支持你! 现在2014年8月24日了,搞定Django了没?

Tim 08-30 10:12

@ULTra ,果断支持你! 现在2014年8月份了,搞定Django了没?

smilesister 09-10 06:29

@ULTra ,果断支持你! 现在2014年9月10日了,搞定Django了没?

匿名读者 10-16 10:41

@ULTra ,果断支持你! 现在2014年10月16日了,搞定Django了没?

misutt 10-19 11:17

@ULTra ,果断支持你! 现在2014年10月19日了,搞定Django了没?

console 10-21 14:54

@ULTra ,果断支持你! 现在2014年3月份了,搞定Django了没?

console 10-21 14:54

@ULTra ,果断支持你! 现在2014年10月21了,搞定Django了没?

@ULTra ,果断支持你! 现在2014年10月21了,搞定Django了没? 11-01 06:59

冯日 11-07 06:11

@ULTra ,果断支持你! 现在2014年10月21了,搞定Django了没? 搞定了发个网址哦!

it 11-17 12:07

@ULTra ,果断支持你! 现在2014年10月21了,搞定Django了没?

bp 12-28 12:58

@ULTra ,果断支持你! 现在2014年12月28了,搞定Django了没?

等待 01-05 02:41

@ULTra ,果断支持你! 现在2015年1月5了,搞定Django了没?

MTH 01-23 07:59

@ULTra ,果断支持你! 现在2015年1月23了,搞定Django了没?

我是作者 01-25 04:47

不看就走,墨迹啥! 你行你上,不行别bb。

01-25 04:49

@ULTra ,果断支持你! 现在2015年1月25了,搞定Django了没?

不是我 01-25 19:28

@ULTra ,果断支持你! 现在2015年1月26了,搞定Django了没?

Matt 02-07 03:04

@ULTra ,果断支持你! 现在2015年2月07了,搞定Django了没?

nemo 02-13 06:57

@ULTra ,果断支持你! 现在2015年2月13了,搞定Django了没?

tt 03-17 13:58

@ULTra URL?

abuchi 03-25 16:39

@ULTra ,果断支持你! 现在2015年2月26了,搞定Django了没?

xiaole 05-06 12:27

@ULTra ,果断支持你! 现在2015年05月份了,搞定Django了没?

QQasdhy 05-06 12:33

@ULTra ,果断支持你! 现在2015年5月6日了,搞定Django了没?

@ULTra ,果断支持你! 现在2015年5月6日了,搞定Django了没? 06-05 09:03

地瓜 06-18 09:59

@ULTra ,果断支持你! 现在2015年6月18日了,搞定Django了没?

gaomei? 07-07 13:05

@ULTra ,果断支持你! 现在2015年7月7日了,搞定Django了没?

mr.liu 08-06 02:11

@ULTra ,果断支持你! 现在2015年7月7日了,搞定Django了没?

Laoda Luo 08-18 14:13

@ULTra ,果断支持你! 现在2015年8月18日了,搞定Django了没?

hhhhhhh 09-01 09:57

@ULTra ,果断支持你! 现在2015年9月1日了,搞定Django了没?

匿名读者 09-12 07:21

@ULTra ,果断支持你! 现在2015年9月12日了,搞定Django了没?

xu 10-17 06:19

@ULTra ,果断支持你! 现在2015年10月份了,搞定Django了没?

mao 11-17 22:08

@ULTra ,果断支持你! 现在2015年11月17了,搞定Django了没?

匿名读者 12-11 09:12

@ULTra ,果断支持你! 现在2015年12月11了,搞定Django了没?

匿名读者 12-14 12:48

@ULTra ,果断支持你! 现在2015年12月14了,搞定Django了没?

CopyLeft 12-18 03:04

@ULTra ,果断支持你! 现在2015年12月18了,搞定Django了没? URL?

nohtyp 12-22 07:55

@ULTra ,果断支持你! 现在2015年12月22了,搞定Django了没?

容嬷嬷 12-31 10:06

@ULTra ,果断支持你! 现在2015年12月31了,搞定Django了没?

Raymond_jc 02-28 01:50

笔者辛苦啦!

cc 03-31 13:19

@ULTra ,果断支持你! 现在2015年12月31了,搞定Django了没?

cc 03-31 13:19

@ULTra ,果断支持你! 现在2016年3月31了,搞定Django了没?

twelve 05-13 05:24

@ULTra ,果断支持你! 现在2016年5月13了,搞定Django了没?

Aaron 05-20 08:12

@ULTra ,果断支持你! 现在2016年5月20了,搞定Django了没?

S_Mh 05-28 02:51

@ULTra ,果断支持你! 现在2016年5月28了,搞定Django了没?

wususu 05-29 10:57

@ULTra ,果断支持你! 现在2016年5月29了,搞定Django了没?

匿名读者 07-04 14:20

@ULTra ,果断支持你! 现在2016年7月4了,搞定Django了没?

Belter xin 08-30 06:55

@ULTra ,果断支持你! 现在2016年8月30了,搞定Django了没? O(∩_∩)O哈哈~

test 09-21 14:41

@ULTra ,果断支持你! 现在2016年9月21了,搞定Django了没?

bealike 10-11 02:05

@ULTra ,果断支持你! 现在2016年10月11了,搞定Django了没? 等你好几年了

我是作者 10-12 09:41

哈哈,起名叫我是作者的牛逼

匿名读者 10-24 13:23

@ULTra ,果断支持你! 现在2016年10月24了,搞定Django了没? 等你好几年了

匿名读者 02-07 05:35

@ULTra ,果断支持你! 现在2017年2月了,搞定Django了没? 等你好几年了

hhh 02-14 04:15

@ULTra ,果断支持你! 现在2017年2月14号了,搞定Django了没? 等你好几年了

匿名读者 02-15 06:21

@ULTra ,果断支持你! 现在2017年2月15号了,搞定Django了没? 等你好几年了

李先生 03-07 08:30

太喜欢DjangoBook了

vanpersiexp 05-11 03:12

@ULTra ,果断支持你! 现在2017年5月11号了,搞定Django了没? 等你好几年了

littlej 05-14 03:29

没希望了,没希望了,楼下的不要在等了。啊哈哈

啦啦啦啦 06-18 05:56

还有这种操作?

lvhua 11-09 06:08

HTTP_REFERER – The referring URL, if any. (Note the misspelling of REFERER.) 原文照翻

lvhua 11-09 06:09

@ULTra ,果断支持你! 现在2017年11月9号了,搞定Django了没? 等你好几年了

lee 12-07 03:11

hahahhahahhah

匿名读者 12-07 03:59

haode

猪头哥哥 12-08 06:52

@ULTra ,果断支持你! 现在2017年12月8日了,搞定Django了没?

Andy 12-11 08:19

@ULTra ,果断支持你! 现在2017年12月8日了,搞定Django了没?

lyz 12-27 03:35

@ULTra ,果断支持你! 现在2017年都快过了,搞定Django了没?

dechoyu 01-31 03:51

这种事情还是交给我来做吧,hiahiahia

test 03-10 13:09

@ULTra ,果断支持你! 现在2018年都快过了,搞定Django了没

Srive 07-06 08:24

@ULTra ,果断支持你! 现在2018年过一半了,搞定Django了没

Adam Ding 07-18 06:08

@ULTra ,果断支持你! 现在已经是2018年7月18号了,搞定Django了没

Sai 08-14 01:58

@ULTra ,果断支持你! 现在已经是2018年8月14号了,搞定Django了没

匿名读者 01-11 03:30

@ULTra ,果断支持你! 现在2019年1月11日了,搞定Django了没

guanhua zhan 07-28 02:51

@ULTra ,果断支持你! 现在2019年7月28日了,搞定Django了没

我是作者 02-08 10:46

666

Lily Paper 10-29 13:20

@ULTra ,果断支持你! 现在2020年10月29日了,搞定Django了没?

TDXR 02-05 10:16

@ULTra ,果断支持你! 现在2021年2月5日了,搞定Django了没?

对这一段的评论会显示在这里

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

lianjie.ning 10-11 11:45

huanbaojieneng 12-18 02:18

http://baike.baidu.com/view/953191.htm

jim 04-13 06:07

给一个优雅的回应,这句话用的好

对这一段的评论会显示在这里
# BAD!
def ua_display_bad(request):
    ua = request.META['HTTP_USER_AGENT']  # Might raise KeyError!
    return HttpResponse("Your browser is %s" % ua)

# 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)
boban 12-04 14:53

备注一下:dict.get(key,default=None) 对字典dict 中的键key,返回它对应的值value,如果字典中不存在此键,则返回default 的值(注意,参数default 的默认值为None)

vose 12-26 14:36

谢谢楼上!

shity boy 11-07 11:44

thanks boban.

tt 03-17 14:08

lss+1

michael 11-25 13:38

现在Python好像提倡用in了吧,不提倡用get了吧 ``` if key in dict: pass else: pass ```

Haibo Hao 01-07 16:19

谢谢楼上!

对这一段的评论会显示在这里

我们鼓励你动手写一个简单的view函数来显示 request.META 的所有数据,这样你就知道里面有什么了。 这个view函数可能是这样的:

对这一段的评论会显示在这里
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))
    return HttpResponse('<table>%s</table>' % '\n'.join(html))
wyattwang 10-26 12:47

这块内容用模板系统来实现,我自己做了一个,但没成功,我把模块做成一个文件,然后在模板中来for迭代想生成表格,用的是"for value in values",内容用的value.keys和values.values,没有成功呢,有做成功的朋友吗?交流下代码。

@7gong 10-29 17:41

楼上的同学,建议你对value再进行一次遍历即可,代码如下(只需对模板文件进行修改即可): <table id=showmeta > {% for value in values%} <tr> {% for v in value%} <td >{{ v }}</td> {% endfor %} </tr> {% endfor %} </table>

wyatt 12-27 12:48

<code lang='python'> print 'hello' </code>

wyatt 12-27 12:49

想测试下看能不能支持太码,看来不行呀。

wyatt 12-27 13:38

@二楼,这种遍历的方式我看了好久,结果是有了,但不能理解呀,这个不能用.号访问吗?

jadesoul 12-30 10:04

貌似这样就可以了,是字符集的问题 values = request.META.items() values.sort() html = [] for k, v in values: html.append(u'<tr><td>%s</td><td>%s</td></tr>' % (k, str(v).decode('gbk'))) return HttpResponse('<table>%s</table>' % '\n'.join(html))

phoenix 02-16 14:39

你可以用用 for key in request.GET 获取所有的键-->你可以用用 for key in request.GET.keys() 获取所有的键 MS应该是这样的

orisiccs 05-31 06:39

{% extends 'base.html' %} {% block content %} <table> {% for k,v in values %} <tr><td>{{k}}</td><td>{{v}}</td></tr> {% empty %} <tr><td>..</tr></td> {% endfor %} </table> {% endblock %} 然后views这边是 def display_meta(request): values = request.META.items() return render_to_response("metaapp/meta.html" , locals())

JenGuo 06-07 07:31

views 可以这么写def display(request): values=request.META.items() values.sort() t=get_template('meta.html') html=t.render(Context({'values':values})) return HttpResponse(html) 模板:<table> {% for k,v in values %} <tr><td>{{k}}</td><td>{{v}}</td></tr> {% endfor %} </table>

lili 08-31 12:43

按照jadesoul的方法,终于 解决了

QiaoY 10-11 08:53

应该是系统编码的问题吧?我在CentOS6.0下这个代码可以正常运行

Qi 10-25 04:27

要使用render_to_response别忘了传递字典,我这个是可以的: 函数: def display_meta(request): values = request.META.items() values.sort() return render_to_response('meta.html',{'values':values}) 模板: {% extends 'base.html' %} {% block content %} <table> {% for key,value in values %} <tr> <td>{{ key }}</td> <td>{{ value }}</td> </tr> {% empty %} <tr><td>NoData!</td><td>CheckIt!</td></tr> {% endfor %} </table> {% endblock %}

jyd 01-19 03:33

Qi 说的就行了。render_to_response时候在values压入字典中传过去。 如: def display_meta(request): return render_to_response('hello.html', { 'values': request.META.items()}); 这样子,模板里面就能使用values变量了。如:{% for k, v in values %}

keroro 08-28 19:17

我是直接用Template : 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))

keroro 08-28 19:18

上面的发错成原文了,下面这个是用Template的 : t = Template('<table><td> {{ index }} </td><td> {{ value }} </td></table>') html = "" for index, value in request.META.items() : html = html + t.render(Context(locals())) return HttpResponse(html)

sebastian.wade 12-29 09:08

@jyd 你的方法还可以再改进的.

Siyuan 02-05 08:23

<table> {% for k, v in values %} <tr><td>{{k}}</td><td>{{v}}</td></tr> {% endfor %} </table>

柳竹溪 02-21 02:29

<html> <body> <table> {%for k,v in values %} <tr><td>{{ k }}</td><td> {{ v }} </td></tr> {%endfor%} </table> </body> </html> 直接这样! views.py def display_meta(request): values=request.META.items() values.sort() t=get_template('meta.html') html=t.render(Context({'values':values})) return HttpResponse(html)

fc2002002002 02-21 06:56

view.py::: def display_meta(request): values = request.META.items() values.sort() return render_to_response('meta.html',locals()) meta.html::: <html> <body> <table> {% for k,v in values %} <tr> <td> {{ k }} </td> <td> {{ v }} </td> </tr> {% endfor %} </table> </body> </html>

athos 03-12 09:56

来个简洁版的: views: from django.shortcuts import render_to_response def model_meta(request): values = request.META.items() values.sort() return render_to_response('meta.html', {'all_meta': values}) 模板: <table> {% for k in all_meta %} <tr><td>{{ k.0 }}</td><td> {{ k.1 }}</td></tr> {% endfor %} </table>

pzpz 03-20 08:14

测试了代码,其中values.sort()错误,取消正常 错误: AttributeError: 'dict_items' object has no attribute 'sort'

鱼小丑 04-25 13:56

我用模版实现了一遍,然后提示我cannot convert float infinity to integer是怎么回事

Kevin 06-20 06:46

实例代码中:return HttpResponse('<table>%s</table> % '\n'.join(html)。我感觉,'\n'在显示效果上是多余的,真的是多余的,我知道join()的函数用法。大家有没有觉得,如果用''.join(),可以实现相同的功能?我的邮箱啊,yan95207396@126.com,哎,这么强大的评论系统,网站作者好像没有好好利用啊!!!!!

alie 07-05 01:18

jadesoul 2010-12-30 18:04:25 貌似这样就可以了,是字符集的问题 values = request.META.items() values.sort() html = [] for k, v in values: html.append(u'<tr><td>%s</td><td>%s</td></tr>' % (k, str(v).decode('gbk'))) return HttpResponse('<table>%s</table>' % '\n'.join(html)) 的确可以。

zhanhe 09-03 14:32

'dict_items' object has no attribute 'sort'

niuyicaho 10-14 09:12

for v in values: c=Context({'v':v}) html.append(t.render(c)) 将每个 tr 标签内的两块内容存为数组 模板中: 1) <tr> {% for i in v %} <td>{{v.0}}</td> <td>{{v.1}}</td> </tr> 2) <tr> {% for i in v %} <td>{{i}}</td> {% endfor %} </tr> 都可以解决

niuyichao 10-14 09:40

上个代码有点小问题,这个测试都可以 1.for v in values: html.append(v) return render_to_response('display_meta.htm',{'v':html}) <html><body><table> {% for i in v %} <tr> <td>{{i.0}}</td> <td>{{i.1}}</td> </tr> {% endfor %} <table></body></html> 2. t=get_template('display_meta.htm') for v in values: c=Context({'v':v}) html.append(t.render(c)) return HttpResponse('<table>%s</table>' % '\n'.join(html)) <!--<tr> {% for i in v %} <td>{{v.0}}</td> <td>{{v.1}}</td> {% endfor %}</tr> --> <tr> {% for i in v %} <td>{{i}}</td> {% endfor %} </tr>

agon 10-22 04:05

报'dict_items' object has no attribute 'sort'错误的,字典是没办法sort的,转成list后再sort,list(request.META.items())

打点滴 10-25 06:49

我的是下面,照搬转换,OK def display_meta2(request): values = request.META.items() values.sort() m1m2=values return render_to_response('request_test.html', {'m1m2':m1m2}) <html> <table> {% for m1,m2 in m1m2 %} <tr><td>{{m1}}</td><td>{{m2}}</td></tr> {% endfor %} </table> </html>

dean 10-31 05:22

我的做法是直接传递req.META,在模板内打印出来 {% for x in meta.items %} {{x}} </br> {%endfor%}

桃子 11-12 09:44

我会报错:Exception Value: 'utf8' codec can't decode byte 0xc5 in position 29: invalid continuation byte

匿名读者 04-19 09:08

空评论也会提交?

匿名读者 04-19 09:13

<script>alert('test');</script>

Adamee@foxmail.com 05-22 08:37

原样copy进views.py里面,再在urls.py里面import一下该方法,配置一下路由表,然后就可以了from APPNAME.views import display_meta///// url(r'^meta/$', display_meta),

alexcool 07-08 13:30

values.sort()在python 3.x会出错,要改成 values = sorted(values)

yubg 08-05 08:36

此处在python3中应将values.sort()改为sorted(values)。

seven 08-06 08:34

views: return HttpResponse('a.html',locals()) a.html: <ul> {% for k, v in values %} <li>this is key :{{ k }} <br> this is value:{{v}}</li> {% endfor %} </ul>

冯日 11-07 06:25

adoo 01-21 06:10

尝试写了一下,都显示得乱七八糟,主要是自己不懂HTML的标签,还是例子里写的优美。

444371050 02-27 05:35

出现500页面(500内部服务器错误)

maojm 06-27 12:56

如果遇到ascii decode错误可以在Python安装目录lib/mimetype.py文件import下以下代码 if sys.getdefaultencoding() != 'gbk': reload(sys) sys.setdefaultencoding('gbk')

李辉 09-10 03:58

这样改吧 return render_to_response('display_meta.html', {'item_list': values}) <table> {% for key, value in item_list %} <tr><td>{{ key }}</td><td>{{ value }}</td></tr> {% endfor %} </table>

HelloDjango 05-21 12:57

pyhon3: values = sorted(values, key=lambda x: x[0])

Belter xin 08-30 07:58

@李辉的可行,补充一下。主要修改两个文件,第一步:在之前的temblates文件夹(~/djcode/mysite/mysite/templates)中添加一个文件"display_meta.html",内容如下: <table> {% for k, v in values %} <tr> <td>{{k}}</td> <td>{{v}}</td> </tr> {% endfor %} </table> 第二步:修改books文件夹下的views.py文件,先import一个函数from django.shortcuts import render_to_response,然后将示例中display_meta函数中的4-6行注释掉,添加return render_to_response('display_meta.html', {'values': values})。

Belter xin 08-30 08:02

注释掉4-7行,最后books/views.py文件中的内容如下: from django.shortcuts import render_to_response # Create your views here. def display_meta(request): values = request.META.items() values.sort() return render_to_response('display_meta.html', {'values': values})

lvhua 11-09 06:33

python3实现,view.py文件内容: def display_meta(request): values = request.META.items() values = sorted(values, key=lambda x: x[0]) return render_to_response('display_meta.html', {'values': values}) templates下创建display_meta.html,内容为<table> {% for k, v in values %} <tr> <td>{{k}}</td> <td>{{v}}</td> </tr> {% endfor %} </table> url.pyt添加:url(r'^hello$', view.display_meta),

lyz 12-27 03:49

Django2.0+Python3.6 验证ls是正确的

猪头哥哥 01-09 07:38

def display_meta(request): values = request.META.items() return render(request, 'display_meta.html', {'values': values}) =================== {% block content %} {% for k,v in values %} <ul> <li>{{ k }}</li> <li>{{ v }}</li> </ul> {% endfor %} {% endblock %} ============== url(r'^meta$', display_meta), 在这里可以从你的views里面import *这样就不会找不到函数了

blackysy 07-03 07:29

python3 + django 2.2.2版本代码示例: views.py: def display_meta(request): values = request.META.items() values = sorted(values, key=lambda x: x[0]) return render_to_response('display_meta.html', {'meta': values}) templates: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>request meta</title> </head> <body> <table border="1"> <tr> <th>request</th> <th>info</th> </tr> {% for k, v in meta %} <tr> <td>{{ k }}</td> <td>{{ v }}</td> </tr> {% endfor %} </table> </body> </html> url.py: path('meta/', views.display_meta),

jiangm_ 07-05 02:01

怎么包含了全部的环境变量?安全不?

jiangm_ 07-05 02:06

怎么包含了全部的环境变量?安全不? {% for k,v in request.META.items %} <tr> <td>{{k}}</td> <td>{{v}}</td> </tr>...

对这一段的评论会显示在这里

做为一个练习,看你自己能不能把上面这个view函数改用Django模板系统来实现,而不是上面这样来手动输入HTML代码。 也可以试着把前面提到的 request.path 方法或 HttpRequest 对象的其它方法加进去。

匿名读者 12-18 01:33

是这个吗

匿名读者 12-18 01:33

http://www.oschina.net/code/snippet_116018_12444

zxw 07-25 01:00

http://zxwwyz.blog.163.com/blog/static/207128210201362585956205/

zzm88 07-25 09:34

感谢2L!可以运行~有一个小地方需要修改:<table>标签应该在循环外面,不然每次循环都会生成一个表格的话,就不能产生对齐的效果。

talent 10-09 03:32

对于出现TemplateDoesNoteExist错误的同学,请参考SO上的这个回答(关于TEMPLATE_LOADERS如何工作): http://stackoverflow.com/questions/12837440/template-loading-locations

tyroger 10-14 13:44

坑爹的中文路径CLASSPATH,导致编码报错,改成对字符串decode('gbk')问题得以解决 def display_meta1(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.decode('gbk') if type(v)==types.StringType else v)) return HttpResponse('<table>%s</table>' % '\n'.join(html))

千里山南 01-04 14:28

http://1.chongyang.duapp.com/33/

Adamee@foxmail.com 05-22 08:42

import sys reload(sys) sys.setdefaultencoding('gbk') in setting.py

Rying 01-09 08:37

{% extends "base.html" %} {% block display_meta %} <table> {% for k,v in values %} <tr> <td>{{ k }}</td> <td>{{ v }}</td> </tr> {% empty %} <tr> <td>NoData!</td> <td>CheckIt!</td> </tr> {% endfor %} </table> {% endblock %} 使用了base.html,需要在其中添加block displaymeta {% block display_meta %}{% endblock %}

gepoe 04-05 07:55

{% extends "dateapp/base.html" %} {% block content %} <table> {% for k,v in values %} <tr> <td>{{ k }}</td> <td>{{ v }}</td> </tr> {% empty %} <tr> <td>NoData!</td> <td>CheckIt!</td> </tr> {% endfor %} </table> {% endblock %}

我是作者 10-12 10:24

def display_meta(request): meta = request.META.items() meta.sort() return render_to_response('request.html',{'meta_line':meta})

stonycat 08-02 07:18

Django1.11 python3: 在books/views.py from django.shortcuts import render_to_response def display_meta(request): values = request.META.items() values = sorted(values, key=lambda x: x[0]) return render_to_response('display_meta.html', {'values': values}) 在mysite/urls.py添加两行: from books.views import display_meta url(r'^display/$', display_meta), #display链接名字是自己起的 在mysite/templates/下确保有display_meta.html <table> {% for k, v in values %} <tr> <td>{{k}}</td> <td>{{v}}</td> </tr> {% endfor %} </table> 然后运行python manage.py runserver 打开响应链接+/display.html 即可显示

10-03 13:42

为什么要用sorted()

猪头哥哥 12-08 07:24

比较简单的一个方法 def display_meta(request): values = request.META.items() return render(request,'request.html',{'list':values}) {% for key,value in list %} {{ key }}======={{ value }}<br> {% endfor %}

对这一段的评论会显示在这里

提交的数据信息

对这一段的评论会显示在这里

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

freedoom 05-19 16:08

关于post 和 get : http://blog.csdn.net/gideal_wang/article/details/4316691

kobegai 01-22 09:05

不得不评,忍不住了

Xavier 07-20 03:40

楼上为什么要忍呢 :D

对这一段的评论会显示在这里

类字典对象

对这一段的评论会显示在这里

我们说“request.GET和request.POST是类字典对象”,意思是他们的行为像Python里标准的字典对象,但在技术底层上他们不是标准字典对象。 比如说,request.GET和request.POST都有get()、keys()和values()方法,你可以用用 for key in request.GET 获取所有的键。

邓鹏 03-25 07:07

我们会稍后讲到-》我们稍后会讲到

张永汀 12-20 01:46

你可以用用多了一个‘用’

bart 07-30 11:38

用用也挺不错的

new 08-25 12:51

好的

对这一段的评论会显示在这里

那到底有什么区别呢? 因为request.GET和request.POST拥有一些普通的字典对象所没有的方法。 我们会稍后讲到。

匿名读者 03-25 07:02

我们会稍后讲到-》我们稍后会讲到

xu 10-17 06:29

难倒是鸭子类

猪头哥哥 12-08 07:37

这一点往后稍一稍

对这一段的评论会显示在这里

你可能以前遇到过相似的名字:类文件对象,这些Python对象有一些基本的方法,如read(),用来做真正的Python文件对象的代用品。

对这一段的评论会显示在这里

POST数据是来自HTML中的〈form〉标签提交的,而GET数据可能来自〈form〉提交也可能是URL中的查询字符串(the query string)。

wyatt 12-27 13:55

POST与GET,第一次看个的时候,可能自己读得不仔细,没搞清楚这两个有什么样的区别,这次看清楚了。GET数据收集既有Form,也有Url传递的参数。

automake 06-26 16:04

GET方法主要是从URL中接受参数。即使是form的参数也是编码在url中,所以一般接受的信息不多,如果接受信息多的话就用POST

lala 10-24 20:01

可以google一下post与get的区别,挺大。

喻峰 04-25 15:26

一般在浏览器中输入网址访问资源都是通过GET方式;在FORM提交中,可以通过Method指定提交方式为GET或者POST,默认为GET提交 Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE URL全称是资源描述符,我们可以这样认 为:一个URL地址,它用于描述一个网络上的资源,而HTTP中的GET,POST,PUT,DELETE就对应着对这个资源的查 ,改 ,增 ,删 4个操作。到这里,大家应该有个大概的了解了,GET一般用于获取/查询 资源信息,而POST一般用于更新 资源信息(个人认为这是GET和POST的本质区别,也是协议设计者的本意,其它区别都是具体表现形式的差异 )。

树不开叉 08-27 12:21

楼上的话好像是limodou说的吧

猪头哥哥 12-08 07:40

在网页端 get和post区别之一就是get是明文 post则不是 而且get一般用于查询就是传一个查询字符串 取数据 相比之下post更全面更安全

匿名读者 07-19 02:10

ls正解。

对这一段的评论会显示在这里

一个简单的表单处理示例

对这一段的评论会显示在这里

继续本书一直进行的关于书籍、作者、出版社的例子,我们现在来创建一个简单的view函数以便让用户可以通过书名从数据库中查找书籍。

对这一段的评论会显示在这里

通常,表单开发分为两个部分: 前端HTML页面用户接口和后台view函数对所提交数据的处理过程。 第一部分很简单;现在我们来建立个view来显示一个搜索表单:

对这一段的评论会显示在这里
from django.shortcuts import render_to_response

def search_form(request):
    return render_to_response('search_form.html')
kk 06-17 11:49

render_to_response()这个函数没介绍过。像是从文件中加载模板,但又缺少render对象…不知到作何解释。

tet 07-05 10:12

render_to_response()前面有解释

scarl 07-27 03:03

1楼不是从开头一直看下来的?

Rex.Ye 01-11 05:38

1L请看【模板】那一章

匿名读者 05-13 06:41

return render_to_response('search_form.html')中,'search_form.html'后面需要加一个英文逗号才行

��� 05-28 23:49

����������ͨ����������������ʱ�վ�����Ķ������Ͻ���������Ļ �߿����13�߿�¼ȡ��-�߿�����2013�߿�����,��ǰ���߷�������а�������-�����- 2013���� �������-���� -2013�������-�������-ȫ���� -2013������� 2013ȫ���� -��������� -�߿�ѧϰ� - 2013�������ǿ -2013�����������-���ҵ�� -������ -���� -����ѧУ -�߿���� -������-�߿����ʱ��-������ -����ϰ - 2013�߿����� -2013���а�� -��� -������ -�����߿�� -����߿�� -�㶫�߿�� -ɽ���߿��- ����߿�� -����߿�� -�����߿�� -����߿�� -�����-���߿�� -����߿�� -�����߿�� -���߿��- ���ո߿�� -���߿��- ����߿�� -����߿�� - ���߿��-����߿��-2013�߿���ϰȫ���.�����������������073178.com����������en.073178.com����������gyu.073178.com����������xiehouyu.073178.com ����������hua.073178.com����������������������������ȵ��ϵ���� �ַ ��www.073178.com//�������/������� 8621

streethacker 07-26 08:28

英文原版中使用的是render,我用的django 1.4,在第4章中按照实例使用render_to_response执行正确,但这个地方始终提示template does not exist,改成render后才运行成功。实在没有弄明白怎么回事。 render和render_to_response的区别是什么?译版何必画蛇添足的将render改为render_to_response呢?

李嘉燊 08-12 16:38

回LS,两个函数的区别就是render函数在最后return要多传一个request参数,你注意看

liujunhao 10-10 09:36

这个地方要在setting.py中配置TEMPLATE_DIRS 例如: TEMPLATE_DIRS = ( 'D:/Python27/Scripts/newtest/newtest/books', )

苏国峰 10-15 16:47

TEMPLATE_DIRS = ( os.path.join(os.path.dirname(__file__), 'templates').replace('\\','/'), u'f:/djangosite/books/templates', 一次性成功,哈哈。

Adamee 05-23 01:01

from django.shortcuts import render OR from django.shortcuts import render_to_response

杨浩 05-11 13:41

在app里面新建templates目录,Django会自动搜索里面的html文件,不用在setting.py里面设置了。

安铺靓仔 12-06 07:56

这个是app里面的

对这一段的评论会显示在这里

在第三章已经学过,这个view函数可以放到Python的搜索路径的任何位置。 为了便于讨论,咱们将它放在 books/views.py 里。

对这一段的评论会显示在这里

这个 search_form.html 模板,可能看起来是这样的:

Doming 07-05 18:22

如果不知道放哪里的话 去看看第四章的教程 我就在这找了半天错

洛洛 08-27 12:32

这个文件可以放在任何可以被import的地方,但是必须在setting里面设置好文件放置的位置。 当然,比较妥帖的办法是放到之前设置好的放模板文件的文件夹下。

Feliz 03-30 05:20

按照这个教程的流程下来,最好是在books这个APP里面新建一个文件夹,比如:templates。把search_form.html文件放到此文件夹中,最后把这个文件夹的路径添加到settings里的TEMPLATE_DIRS里面。

血衫非弧 07-11 01:23

络络说的是对的=。=

idailylife 05-03 13:29

恩,洛洛 说的对,settings.py里面的模板目录要把当前这个的目录加上不然找不到的。

qieli 08-12 10:37

本文第四章有详细说明 TEMPLATE_DIRS = ( '/home/django/mysite/templates' )

sebastian.wade 12-27 12:37

django1.4.3的配置(win&linux): TEMPLATE_DIRS = ( os.path.join(os.path.dirname(__file__), 'templates').replace('\\','/'), )

Jerry 12-28 09:54

我也遇到了这个问题,但稀里糊涂的解决了。是这样的:版本Django version 1.4.2 文件目录是三层的myweb/src/book/views.py. views中的内容都原样。urlpy照这个搞不对,我改成这样:from myweb import views,从最顶层引入,然后再次运行,页面左上角的search表单神奇般的出来了。希望对你有点参考意义。

Rex.Ye 01-11 06:09

这里做成功了,search_form.html可以放到放到任何已经注册的路径下。 比如放到“E:\PythonWebSite\mysite\templates”路径下,那么就在 settings.py 的TEMPLATE_DIRS中加上"E:\PythonWebSite/mysite/templates", 主要:这里的路径要用"/"不能用"\",否则会报错。 我的是python2.7,Django 1.4

Rex.Ye 01-11 06:09

这里做成功了,search_form.html可以放到放到任何已经注册的路径下。 比如放到“E:\PythonWebSite\mysite\templates”路径下,那么就在 settings.py 的TEMPLATE_DIRS中加上"E:\PythonWebSite/mysite/templates", 注意:这里的路径要用"/"不能用"\",否则会报错。 我的是python2.7,Django 1.4

xta烫 05-12 01:29

楼上Rex.Ye,请问你的是什么操作系统?

Adamee 05-23 01:42

1.6的默认加载了,不需要再在配置里面添加模板路径了,默认就在APP/templates 文件夹里面,当然,得自己建这个文件夹

mihello 08-09 04:49

可以是project 里面的templates 也可以是app里面的templates 只要Django搜到就可以,规范来说既然这个是app books的页面,还是放在books/templates 好。可以参考官网教程

herrdu 04-30 10:16

文件路径 E:\django\mysite\templates

对这一段的评论会显示在这里
<html>
<head>
    <title>Search</title>
</head>
<body>
    <form action="/search/" method="get">
        <input type="text" name="q">
        <input type="submit" value="Search">
    </form>
</body>
</html>
ruandao 06-08 07:41

如果你在app中建立templates文件夹 然后在setting中的 INSTALLED——APPS = ( 。。。 'app_name', # 不要写你的项目名称 , 像'projects_name.app_name'是不好的 。。。 ) 那么系统会自动在app中的templates文件夹寻找是否有合适的模板

Woods 10-26 02:07

标准来说,input需要关闭标签。即<input .../>

苏国峰 10-16 15:58

woods说的对

Adamee 05-23 02:41

action里面的路径暂时还访问不到吧? 下文有没有定义/search/ ? 接着看下来...

Johnson 07-11 02:55

这里面的<form></form>里面的查询内容是html内支持的吗?这里面没有django的东西吧?

syshu 10-14 05:14

表单动作里面填写/search/是绝对路径,search/是相对路径,会变成/search-form/search/

请叫我雷锋 03-24 16:32

/search/这个地方。一拼接就变成http://127.0.0.1:8000/search/?q=xxx这个肯定是错的。。。所以。。/search/要改成/search

horizonshd 09-15 05:00

Django-1.11.3中,search_form.html 模板文件可以放在项目中的任何一个app的模板文件中,比如books/templates下,唯一要注意的就是各app下的模板文件名要一样,并且得是在settings.py文件中配置的'DIRS'的值。在运行时,Django会自动在这些目录下寻找相应的模板文件。

llxxyy 03-25 10:55

syshu说得对,search/相对路径

对这一段的评论会显示在这里

而 urls.py 中的 URLpattern 可能是这样的:

对这一段的评论会显示在这里
from mysite.books import views

urlpatterns = patterns('',
    # ...
    (r'^search-form/$', views.search_form),
    # ...
)
lynzhung 08-10 03:37

此处使用from mysite.books import views 需要取消注释下面两句: from django.contrib import admin admin.autodiscover() 即加上这两句才行,不然要出现找不到books模块

lyzhung 08-10 07:08

在加载books文件夹时,请复制一个__init__.py文件到books中,否则会出现找不到books模块的错误提示

cser 08-30 07:55

from django.contrib import admin admin.autodiscover() django.VERSION 为0.9x的不用.

whille 10-28 18:03

(r'^search-form/$', 'books.views.search_form'),

lastmayday 08-27 03:24

from books import views

hweeken 09-16 19:36

lastmayday 正解。如果文件目录是mysite/books/views.py 的,(区别于mysite/mysite/books/views.py),在这里import的时候要用ls的方式。这问题让我折腾了好久,谢谢lastmayday

江桥 10-12 04:47

被import搞糊涂了,谁教我理解下,我是mysite/mysite/books/views.py,

Jerry 10-12 05:37

路径是d:/mysite/mysite/books/views.py 用from books.views import * 可以但是from books import views就不行,提示找不到search_form

sebastian.wade 12-27 12:34

django版本为:1.4.3的配置(环境为mysite/books/views.py): 添加: from books import views 需要取消注释下面两句: from django.contrib import admin admin.autodiscover()

Jack 01-06 07:58

如果路径是:'/mysite/books/'直接写 from books import views 就行了,不会错的

hellokitty 04-14 11:37

from mysite.views import hello,current_datetime,hours_ahead,mypage,display_meta,search_form (r'^search-form/$', search_form)

rodmanwu 06-09 08:28

whille 的可以,为啥'books.views.search_form'需要单引号呢? 然后我是/mysite/books 用 from books import views

jwfy 09-20 02:40

这里确实需要注意路径,还有一个要注意的就是 (r'^search_from/$') 这里面不需要这个“/$”,我们导入的那是个search_from.html ,后面就不能要/$,否则就会显示找不到网页的。。。

十万个不为什么 09-28 14:46

到这里我算是彻底的被 搞糊途了。 因为最开始建 出的来的文件夹就有两层mysite,而manager.py是在第一层mysite下面的,而urls.py、setting.py、是在mysite/mysite下面的,templates文件夹是在mysite/mysite/template,books是在第一层mysite下面的,好乱啊!!!!

十万个不为什么 09-28 16:10

我推荐看一下这一篇,这一篇最后说了,各个app应该和mysite独立,不应该放在mysite里面。http://site.douban.com/192043/widget/notes/11418540/note/247044376/

o02112 11-10 08:12

我写的是from books.views import *才成功的。

o02112 11-10 08:14

我写的是from books import views才成功的。

天涯明月 12-19 09:53

from books import view from django.contrib import admin admin.autodiscover() urlpatterns = patterns('', #... (r'^search-form/$', views.search-form), #...)

天涯明月 12-19 09:54

from books import view<br/> from django.contrib import admin<br/> admin.autodiscover()<br/> urlpatterns = patterns('',<br/> #...<br/> (r'^search-form/$', views.search-form),<br/> #...)

天涯明月 12-19 09:55

from books import view\n from django.contrib import admin\n admin.autodiscover()<br/> urlpatterns = patterns('',<br/> #...<br/> (r'^search-form/$', views.search-form),<br/> #...)

天涯明月 12-19 09:55

from books import view\n from django.contrib import admin\n admin.autodiscover()\n urlpatterns = patterns('',\n #...\n (r'^search-form/$', views.search-form),\n #...)

Harry 01-07 01:59

此处应该将例子中的 from mysite.books import views 改为 from books import views , 否则会报错!

111 03-26 07:59

到这里大家应该区分一下project与app的区别,之前的例子都是按照在project的思路做下来的,到这里突然换成app肯定会有一些混乱,其实在之前的Templates_dirs时就应该思考一下project与app的区别,看到有评论说默认为templates了,当时就不是很理解,所以深入跟进了一下这个问题,在网上搜以及查官网资料(我用的是1.6.2),然后发现评论所说的其实是针对app的默认设置,从那开始就把project下的代码切换到了app里了。所以大家先别急,耐心的把你project里的代码切换到app里,之后就顺利成章了

chewinggum 04-12 07:18

应该是 form mysite.books import search_form url(r'^search-form',search_form),

Adamee 05-23 01:44

from books.views import hello,current_datetime,hours_ahead,display_meta,search#一路下来我都写了这么多了,留下来参考参考

Adamee 05-23 01:45

url(r'^$', hello),#2 url(r'^admin/', include(admin.site.urls)),#1 url(r'^hello/$', hello),#2 url(r'^time/$', current_datetime), url(r'^time/plus/(\d{1,2})/$', hours_ahead), url(r'^meta/$', display_meta),#一个简单的view函数来显示 request.META 的所有数据 url(r'^search/$', search),

Adamee 05-23 02:01

from books.views import *

Adamee 05-23 02:44

from mysite.books import views 然后再路由表里面又 views.XXX 方法,好像懂了点,不过觉得有点罗嗦

Xavier 07-20 06:43

楼上很多目录都木有放对。。

猪头哥哥 01-10 01:31

1.11版本里面是这样操作的 在books这个app里建立templates文件夹 新建search_from.html 在books里的views.py里写那个函数 使用render记得request参数一定要传,可以继承在project目录里的base.html 并不需要设置目录 写好urls就可以了

对这一段的评论会显示在这里

(注意,我们直接将views模块import进来了,而不是用类似 from mysite.views import search_form 这样的语句,因为前者看起来更简洁。 我们将在第8章讲述更多的关于import的用法。)

yichengshang 01-11 13:48

而不是用类似 rom mysite.views import search_form 这样的语句-----应该为:From mysite.views import search_form

lynzhung 08-10 03:36

此处使用from mysite.books import views 需要取消注释下面两句: from django.contrib import admin admin.autodiscover() 即加上这两句才行,不然要出现找不到books模块

ok 05-09 03:15

直接使用views.search_form import进来,而且上几章的hello也可以使用这方法,views.hello import进来。

xzz 07-09 06:29

在django1.4版本中目录访问出现了变化,在import books这个app的时候不用import mysite.books 而是import books

K 07-15 05:00

同意楼上XZZ说的

Adamee 05-23 02:18

from APPNAME.views import * 反正我是这样成功的,哎

trokey 02-17 16:19

Django Version: 1.7.2 目录结构如下: ./mysite/mysite ./mysite/books ./mysite/templates ./mysite from books.views import search_form 能显示search界面

Andy 12-11 09:28

setting中的模板路径设置:'DIRS': [os.path.join(BASE_DIR, 'app1/templates')], ## 如果模板在APP中,则需设置APP/模板文件夹名称 'DIRS': [os.path.join(BASE_DIR, 'templates')], ## 如果模板在项目中,只需设置模板文件夹名称

对这一段的评论会显示在这里

现在,如果你运行 runserver 命令,然后访问http://127.0.0.1:8000/search-form/,你会看到搜索界面。 非常简单。

Ping 08-14 17:50

访问网页提示:TemplateDoesNotExist at /search-form/,求解!

Jerry 12-28 09:55

我也遇到了这个问题,但稀里糊涂的解决了。是这样的:版本Django version 1.4.2 文件目录是三层的myweb/src/book/views.py. views中的内容都原样。urlpy照这个搞不对,我改成这样:from myweb import views,从最顶层引入,然后再次运行,页面左上角的search表单神奇般的出来了。希望对你有点参考意义。

greeb 05-10 15:07

回ping,我也遇到了这个问题,把‘search-form’改成‘’searchform'就没问题了,当然url.py里也要改,不知道是不是url中不准出现‘-’。

click 06-04 10:30

地址错了,应该是http://127.0.0.1:8000/search_form/

alex 06-09 03:35

我点击了search按钮,浏览器地址栏变成:http://localhost:8000/search-form/?q=aaa,但是,没有任何新网页出现,也没有404网页,没有任何变化,一直停留在search-form页面,是search按钮没起作用吗? 谁能解答一下呢?谢谢

marinegreen 07-02 02:23

报错'module' object has no attribute 'search_form'。已崩溃,之前是可以搜索页面是可以出来的,突然不行了。而且所有写在book.views里的视图都报这个错。

jasper 08-05 07:22

出现mysite.books问题是因为导入的模块应该是boos,不应该是mysite.books。点击网址search-form进不去是正常的,因为网址中出现了-,建议把“-”换成“_”或者另起他名,当然,相应的ulrs.py中也要做相应的改变。

匿名读者 08-12 07:31

setting.py中设置模板路径TEMPLATE_DIRS

skyler 12-24 06:14

差一点把自己绕进去了... project里面的那个views.py 是我们自己建立的,并不是django自己生成的...而app 里面的views 则是django生成的

10-28 12:25

为什么runserver失败了 ,有人和我一样么

qiaoqiao 02-06 21:24

A server error occurred. Please contact the administrator.服务器端有错误。找不到原因

Hover 08-06 04:04

'SafeText' object has no attribute 'get',怎么办?

simple 01-28 11:18

A server error occurred. Please contact the administrator 版本问题吗

猪头哥哥 12-08 07:51

看到这里 我觉得区分project和app是十分必要的

对这一段的评论会显示在这里

不过,当你通过这个form提交数据时,你会得到一个Django 404错误。 这个Form指向的URL /search/ 还没有被实现。 让我们添加第二个视图函数并设置URL:

Adamee 05-23 02:45

果然

对这一段的评论会显示在这里
# urls.py

urlpatterns = patterns('',
    # ...
    (r'^search-form/$', views.search_form),
    (r'^search/$', views.search),
    # ...
)

# views.py

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)
811191000 02-02 03:22

def search(request): if request.GET['q']: #因为form过来的url总是有'q='

yilang qin 04-19 08:37

在views.py中添加from django.http import HttpResponse

ddd 08-05 01:20

为什么要用%r呢?显示出来是u'查询字段,难看死了

CcChen 03-21 15:21

当提交空的内容去搜索的时候,无法获得'You submitted an empty form.'这个结果.而是得到"You searched for: u''"

CcChen 03-21 15:26

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

ok 05-09 03:29

需要添加from django.http import HttpResponse,%r为什么要使用它?还有输出的结果为什么会是You searched for: u'Test'?多了个'u',应该需要google大婶出马了。

Lang 09-08 05:34

1.使用if 'q' in request.GET,是防止没有通过提交表单跳转,如直接访问/search/。可以修改为if 'q' in request.GET: if request.GET['q']: message = 'You searched for: %r' % request.GET['q'] else: message = 'You submitted an empty form.' else: message = 'How did you go to this page?'

Woods 10-26 02:24

@ok u是unicode的标志,因为django里所有的操作都是基于unicode的

cateye 11-28 07:08

综上改良版 def search(request): if 'q' in request.GET: if request.GET['q']: message = 'You searched for: %s' % request.GET['q'] else: message = 'You submitted an empty form.' else: message = 'How did you go to this page?' return HttpResponse(message)

朱振超 07-25 07:38

if 'q' in request.GET.这个不专业。

jason 12-12 08:24

应该把search函数中的 判断改为: if request.GET['q']:

Hujp 01-29 13:09

这里添加的url是不是不应该用$收尾,因为Get表单提交的时候url后面会被追加表单数据,比如/search/?q=,这样的话url就不匹配了,会报错。

Hujp 01-30 12:10

if 'q' in request.GET判断的好处在于即使有人恶意修改了前台表单,后台也能正确处理,而不是报错。仅就这里而言这样的做的意义不大,因为恶意修改的人得到错误也活该,反正也影响不到后台。但是后台逻辑即使在前台表单被串改仍能正常处理这个观念很重要,就像有些表单的输入检查仅在前台做一样,稍微改个表单就可以提交不合法的数据了,而好的应用会在后台“重复”做和前台一样的检查。

jack li 02-10 04:33

'q' in request.GET 的值一直是True. 因为request.GET是一个字典,它一定有一个键是'q' 这里我们要做的是判断'q'这个键的值是否为空,应该写成: if (request.GET['q']):

yooke 05-11 10:33

这里的 if 'q' in request.GET 条件是为了处理用户直接通过比如:http://127.0.0.1:8000/search/来访问,而不是通过http://127.0.0.1:8000/search-form/跳转过来访问时引发的异常。

WildCat 05-14 04:23

if 'q' in request.GET: should be if request.GET("q"):

chu888chu888 06-07 06:38

修改成message = 'You searched for: %s' % request.GET['q']就是中文了

jasper 08-05 08:50

(r'^search-form/$', views.search_form), (r'^search/$', views.search), 我這兩句放在一起爲什麽老是出來:'tuple' object is not callable的錯誤提示,必須要砍掉一個才行

jasper 08-05 09:07

樓上少逗號!!哈哈

zhayefei 08-07 11:32

'You searched for: %s' % request.GET['q'] 用 %s,可以显示 中文,不然就是unicode编码

njw 08-14 07:03

if (request.GET['q']): message = 'You searched for: %s' % request.GET['q'] 可以既显示中文又可以避免'q' in request.GET一直为真的问题

atlas 10-02 08:22

@yooke正解

Harry 01-07 02:18

需要在 views.py 中添加 from django.http import HttpResponse ,否则会报错!

monkey 02-26 07:10

@yooke说的是对的,如果搜索框里输入是空,我们可以不让其跳转,仍然停在此页面比较符合情理,或是弹出提示框也可以。 def search(request): if 'q' in request.GET: message = 'You searched for: %s'% request.GET['q'] if not request.GET['q']: return render_to_response('search_form.html') else: message = 'You submitted an empty form.' return HttpResponse(message)

朱李 03-21 05:11

用request.GET.get('q', '')既可以处理'q'不在request.GET的情况,也可以处理'q'为空的情况。

lll 06-24 02:35

写成 if request.GET['q']:这样有可能会抛出异常,因为当用户修改地址时'q'可能不存在GET请求中,因此会抛出一个nullPointerException

Xavier 07-20 07:06

楼上某位同学的解释很好。

mihello 08-09 05:10

大家解析的很好,如果表单空重定向到本页,下面介绍的应该有redirect。

lsw 08-11 07:11

为什么我在搜索框里输入内容提交后还是提示“You submitted an empty form.”!,帮忙给解答下吧

匿名读者 10-21 14:51

if request.GET['q']:

JohnDHH 07-31 02:36

我使用if request.GET['q']: message = "test search for : %s" % request.GET['q'] else: message = "test submitted an empty from." 才跳转正常

nohtyp 12-22 08:53

如果使用开发环境,比如Pycharm,你可以直接打views,在按alt+Enter,会自动引入

adam 01-13 07:44

if request.GET['q']:

匿名读者 08-18 01:54

if request.GET['q']: 楼上是对的

匿名读者 09-30 09:06

def search(request): if request.GET: if request.GET['q']: message = 'You searched for: %s' % request.GET['q'] else: message = 'You submitted an empty form.' else: message = 'You submitted an empty form.'

lvhua 11-15 02:53

url(r'^search', view.search),

fandeyou 07-31 03:18

r'^search_tiaozhuan/$'

对这一段的评论会显示在这里

暂时先只显示用户搜索的字词,以确定搜索数据被正确地提交给了Django,这样你就会知道搜索数据是如何在这个系统中传递的。 简而言之:

对这一段的评论会显示在这里
  1. 在HTML里我们定义了一个变量q。当提交表单时,变量q的值通过GET(method=”get”)附加在URL /search/上。
  2. 处理/search/(search())的视图通过request.GET来获取q的值。
qcsky 12-29 12:43

通过request.GET['q']来获取q的值

kevin 07-01 09:58

通过筷子夹肉吃肉 通过筷子吃肉 哪个通顺点?楼上太苛刻了。

lala 10-24 20:10

笑喷了

qq_345421243 05-13 07:13

哈哈,2楼举例很好笑

atlas 10-02 08:26

哈哈,举例真心不错,笑喷了

haha 07-04 08:40

这才在看笑话吗

mr.liu 08-06 07:18

haha

对这一段的评论会显示在这里

需要注意的是在这里明确地判断q是否包含在request.GET中。就像上面request.META小节里面提到,对于用户提交过来的数据,甚至是正确的数据,都需要进行过滤。 在这里若没有进行检测,那么用户提交一个空的表单将引发KeyError异常:

邓鹏 03-25 08:23

需要注意的是在这里明确地判断q是否包含在request.GET中 -> 需要注意的是在这里应该明确地判断q是否包含在request.GET中

kevin 07-01 10:39

需要注意的是在这里明确地判断q是否包含在request.GET中。 需要注意的是在这里明确地判断了,q是否包含在request.GET中。

hello 03-14 12:18

%r 应该是%s

Evanlee 09-11 12:21

为什么即使我没填写内容,提交时会显示’q=‘,也就是request.GET中包含q?

tobyjia 12-25 14:16

提交空的时候,并不会引发异常,只会认为q= (空)

streethacker 07-26 08:39

同意ls两位,我提交空的表单时,仅仅是显示为空,并不会出发KeyError。提交空表单时显示如下: You searched for: u''

paulzhao 08-07 15:31

q是上面网页里那个文本输入框的name,在提交的时候,这些会被封装起来,即q=文本内容,这样的显示在url上,那么你的文本框是空的话,url也不过是q=''这样的,如果要走else,就把url的q=改成其它的,比如qs=,这样在GET中就无法找到q的这个key了。

gone_with_wind 06-05 08:04

if request.GET['q'].strip() == '' : message = 'empty form' 再加一个判断,就可以 控制空格

gone_with_wind 06-05 08:23

if not request.GET['q'] : message = 'empty form' 或者这样,就可以 控制空格

yaoge422 03-12 04:37

空的表单不是指不填q的值,而且是url后根本不跟参数

ddd 07-09 05:26

sadadzd

对这一段的评论会显示在这里
# BAD!
def bad_search(request):
    # The following line will raise KeyError if 'q' hasn't
    # been submitted!
    message = 'You searched for: %r' % request.GET['q']
    return HttpResponse(message)
对这一段的评论会显示在这里

查询字符串参数

对这一段的评论会显示在这里

因为使用GET方法的数据是通过查询字符串的方式传递的(例如/search/?q=django),所以我们可以使用requet.GET来获取这些数据。 第三章介绍Django的URLconf系统时我们比较了Django的简洁的URL与PHP/Java传统的URL,我们提到将在第七章讲述如何使用传统的URL。通过刚才的介绍,我们知道在视图里可以使用request.GET来获取传统URL里的查询字符串(例如hours=3)。

HJWAJ 06-23 09:30

所以我们可以使用request.GET,校正拼写错误。

对这一段的评论会显示在这里

获取使用POST方法的数据与GET的相似,只是使用request.POST代替了request.GET。那么,POST与GET之间有什么不同?当我们提交表单仅仅需要获取数据时就可以用GET; 而当我们提交表单时需要更改服务器数据的状态,或者说发送e-mail,或者其他不仅仅是获取并显示数据的时候就使用POST。 在这个搜索书籍的例子里,我们使用GET,因为这个查询不会更改服务器数据的状态。 (如果你有兴趣了解更多关于GETPOST的知识,可以参见http://www.w3.org/2001/tag/doc/whenToUseGet.html。)

wzdxt 07-16 05:32

这里是不是把html的post get 和POST GET DELETE EDIT 搞混了?

gaga 05-18 13:19

英语不好的可以看这里 http://www.w3school.com.cn/tags/html_ref_httpmethods.asp

匿名读者 01-19 06:56

ls给的链接很好!赞一个~

星火 04-20 14:59

这里 POST 和 GET 的区别冒似没说到点上。其实GET 和 POST 目的都是为了将表单数据提交给服务器,所有数据将被组织成 key1=value1&key2=value2&…… 的格式,区别在于,GET会将数据跟在目标URL后面并使用?隔开(如:http://www.baidu.com?q=abcd),POST则将数据放在HTTP协议的body部分提交,从客户端的角度来观察,GET能在URL上明显看到所有提交的数据,而POST的URL仅显示目标地址,傻瓜式抓屏木马则无法得知提交的数据内容,所以类似提交密码等敏感信息时,使用POST比GET更加合适。该使用哪种方式提交,需要根据使用场景而定。

帽子 02-23 02:59

楼上正解

对这一段的评论会显示在这里

既然已经确认用户所提交的数据是有效的,那么接下来就可以从数据库中查询这个有效的数据(同样,在views.py里操作):

对这一段的评论会显示在这里
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.')
呜呜祖拉 07-13 00:58

if 'q' in request.GET and request.GET['q']: 为什么要if 'q' in request.GET这个条件呢?前文中 <form action="/search/" method="get"> <input type="text" name="q"> <input type="submit" value="Search"> </form> 说明‘q’通过GET提交上去的,那么‘q’一定会在request.GET这个字典中的,为什么还要检查一遍呢?

stanzgy 08-30 05:13

这里是检查reuqest.GET[‘q’]的值是否为空。

ruandao 06-08 07:55

if 'q' in request.GET and request.GET['q'] 为什么要 and request.GET['q']呢 前面的'q' in request.GET 已经确定了‘q'有其值啊 那么后面的也必然为true。。

ruandao 06-08 07:58

怎么把我上一条给删了 粗心了

匿名读者 08-12 18:15

...

imagineer 08-13 10:24

if request.GET['q']判断q为空,如果已经有上交表单的动作,q肯定不为空;如果不判断,在地址栏里令q为空,将抛出一个404错误,这就浪费了../seach/这个地址。 后文有个更复杂的例子 q = request.GET['q'] if not q: ...... else: ......

CVWEN 11-17 16:46

'q' in request.GET 是判斷是否有'q'這個key, request.GET['q']判斷是否為' '空值,如果在搜尋框輸入'空白' submit後 if 'q' in request.GET and request.GET['q']會是false

zhangtongle 11-28 03:05

我查找存在的书籍显示的结果是没有这本书 请问有人知道是为何吗

Ever 02-16 13:05

此处的 if 'q' in request.GET and request.GET['q'] 改为 if 'q' in request.GET and request.GET['q'].strip() 是不是好一点。。否则提交一堆空格也会查询的

e2fsck 07-06 05:30

title__icontains 中间是 2 个 _

alex 10-26 07:07

作者,请问下,你的Book你是怎么提交的? 我用你的代码运行,Book明明就是错误的.提示: cant't import Book.. 我只想说,要是英文版的没有这个介绍,我绝对不看这种错误太多的书,很恼火阿!!!麻烦作者你先运行下再介绍好吗

yue 12-17 02:30

其实并不是作者提供的例子不能运行,而是django的版本在不断发展,有很多东西变化了

Jack 01-06 08:40

顶ls

yh 01-31 09:35

如果出现import错误,那就把from mysite.books.models import Book中的mysite删掉

Mango 05-05 15:46

为什么我得到的结果都是没有找到这本书

PhoenixxYang 07-29 05:34

For new version of Django, here would be an issue that request.GET is a QueryDict which is not callable. Using request.GET.get('q') solved it.

paulzhao 08-07 15:39

@PhoenixxYang 我用最新的没问题,自己看看例子,用的是中括号不是小括号

lincy 08-17 03:04

明明存在的书就是说没找到。。。。

lincy 08-17 03:48

关于查询存在的书却显示书不存在的问题,我在百度知道提问了http://zhidao.baidu.com/question/581802637.html,希望知道的可以帮忙解答一下

dj 08-29 08:58

我都无语了,那些说找不到book的人,还总是说本书的翻译,要么你自己没有从头看这本书,要么你就是2,作者多次介绍说版本不同,目录不同,import当然不同啊,连我这个初学者都气愤了。。。

coco 09-05 09:33

楼上正解啊!总埋怨啥啊!这书都出多少年了,Django都1.5.2了,怎么可能没改动,你一个程序员连import都用别人告诉你在自己加???我去,能不能动动脑子啊!不动脑子当什么程序员啊!

cal 10-10 06:14

顶楼上 自己放哪里了 就从运行服务的那个脚本的位置找相对路径就ok了

tommy 10-11 02:57

我用的python2.7 request.GET['q']报错,改为request.GET.get('q','')后运行正常。

匿名读者 01-03 00:40

if 'q' in request.GET and request.GET['q']:的优先级为 if (('q' in request.GET) and (request.GET['q'])):我的的可以这样理解

Harry 01-08 01:38

此处 from mysite.books.models import Book 需要改为 from books.models import Book , 否则会报错

匿名读者 01-24 05:52

if 'q' in request.GET 判断GET有没有q的键 if request.Get['q'] 判断GET['q']对应的值是否非空

lory 03-30 10:49

这个引入路径不对,不知道当时你的层级目录怎样的, 应该也是相对顶级目录来说

bobo1732 05-11 13:56

if语句直接用: if request.GET.get['q'] 不是更简短么,干嘛要用个and?

stevenlee87 07-08 10:09

if 'q' in request.GET and request.GET['q']: 为什么要if 'q' in request.GET这个条件呢?前文中 <form action="/search/" method="get"> <input type="text" name="q"> <input type="submit" value="Search"> </form> 说明‘q’通过GET提交上去的,那么‘q’一定会在request.GET这个字典中的,为什么还要检查一遍呢?

jieni 03-16 06:24

如果不判断 one in request 直接 request.get['one'] 如果request请求参数列表中没有one 而不是有one没有值 则会报错,其实试下就知道了很简单

Chao 11-06 13:08

为什么最后一行不是双引号而是单引号?

CopyLeft 12-18 07:21

按着书来,这里的title_icontains是不是有问题?

hankee 05-29 02:51

新版本的filter参数已经变了,改为title__contains即可

xp 08-09 03:25

@alex 脑子是个好东西,希望你会有

wangyue 10-11 07:15

>>> title__icontains是大小写不敏感匹配。>>> if 'q' in request.GET 用来判断提交的form表单内容参数是否是合法的, if request.GET['q'] 是用来判断提交的q值是否是非空内容。

lyz 12-27 04:27

虽然能正常运行也能查找到,但是Pycharm在Book.objects.filter 这报错?(objects处有下划线提示)

kabumin 06-07 03:52

1 python 3,django2.0中,该处,不需要加icontains,直接title=q即可,加入icontains之后会一直报错

对这一段的评论会显示在这里

让我们来分析一下上面的代码:

对这一段的评论会显示在这里

除了检查q是否存在于request.GET之外,我们还检查来reuqest.GET[‘q’]的值是否为空。

stanzgy 08-30 05:14

应改为"我们还来检查reuqest.GET[‘q’]的值是否为空。"

wl6179 02-23 07:23

应该是“检查来”改成“检查了”~

sebastian.wade 12-27 13:03

在 title 和 contains 之间的双下划线和Python一样,Django也使用双下划线来表明会进行一些魔术般的操作

Radon 09-19 14:45

感谢三楼解释双下划线

对这一段的评论会显示在这里

我们使用Book.objects.filter(title__icontains=q)获取数据库中标题包含q的书籍。 icontains是一个查询关键字(参看第五章和附录B)。这个语句可以理解为获取标题里包含q的书籍,不区分大小写。

对这一段的评论会显示在这里

这是实现书籍查询的一个很简单的方法。 我们不推荐在一个包含大量产品的数据库中使用icontains查询,因为那会很慢。 (在真实的案例中,我们可以使用以某种分类的自定义查询系统。 在网上搜索“开源 全文搜索”看看是否有好的方法)

cjyfff 03-07 04:08

“开源”?

mihello 08-09 11:06

open-source full-text

mihello 08-09 11:07

原文:Search the Web for open-source full-text search to get an idea of the possibilities.)

对这一段的评论会显示在这里

最后,我们给模板传递来books,一个包含Book对象的列表。 查询结果的显示模板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 %}
Woods 10-26 02:31

不需要包含<html>和<body>标签吗?

sylier 01-15 15:12

这里如果要显示作者应该怎了写?直接写book.author会显示成<django.db.models.fields.related.ManyRelatedManager object at 0x025ADA90>这个。

易枭寒 09-28 06:34

<html><head><title>first test</title></head><body>content</body></html>

spinach 10-22 08:19

pluralize是智能添加s或者es么?

匿名读者 05-13 03:21

book改成books,不能查不到。 {% for books in books %} <li>{{ books.title }}</li>

tony 07-16 05:45

<p>Found {{ books|length }} book{{ books|pluralize }}.</p>——其中的“books|length”怎么理解呢?在那一章有解释吗?

jako 09-04 14:21

ls ,在第四章过滤器有讲

Jim 01-26 07:55

此时显示Found 1 book 或者Found 1 books {{ books|pluralize:"es"}}则是加es

TTTsand 09-23 05:35

@jim你好,请问如何测试?这段Html文本时要加入到之前那个Html文本中吗?

mac 12-09 10:42

在模板路径下新建名为 search_results.html 的文件

blue 12-21 11:38

这个html文件需要自己润色,加上<!DOCTYPE html>,<head><body>等内容

mr.liu 08-06 10:14

length与pluralize属于模板标签,{{ books | length }}是计算books中元素个数的;{{ books | pluralize }} 如果books值不是,就返回s,你可以在后面自己添加需要返回的字符串。 模板标签页:http://djangobook.py3k.cn/appendixF/

nohtyp 12-23 01:45

{% for book in books %} <li>{{ book.title }}</li>,不用改,这里book只是一个变量而已,来遍历books

猪头哥哥 12-11 01:11

回顾一下 for循环的用法 for a in b其中a指的是b中每一条记录 a.title中的title是b中的字段名这个必须一致

对这一段的评论会显示在这里

注意这里pluralize的使用,这个过滤器在适当的时候会输出s(例如找到多本书籍)。

imagineer 08-13 10:32

0会被pluralize这个过滤器判断成负数,这...

sebastian.wade 12-27 13:08

"book{{ books|pluralize }}" ---> "pluralize" 如果值不是 1 的话返回 's' 用于 '1 vote' vs. '2 votes' 这种场合.

zlleah 01-05 06:45

就是当单词为复数时,添加一个复数eg:s(默认,可以修改)的后缀。 pluralize Returns a plural suffix if the value is not 1. By default, this suffix is 's'. Example: You have {{ num_messages }} message{{ num_messages|pluralize }}. If num_messages is 1, the output will be You have 1 message. If num_messages is 2 the output will be You have 2 messages. For words that require a suffix other than 's', you can provide an alternate suffix as a parameter to the filter. Example: You have {{ num_walruses }} walrus{{ num_walruses|pluralize:"es" }}. For words that don't pluralize by simple suffix, you can specify both a singular and plural suffix, separated by a comma. Example: You have {{ num_cherries }} cherr{{ num_cherries|pluralize:"y,ies" }}.

Jim 01-26 07:54

此时显示Found 1 book 或者Found 1 books {{ books|pluralize:"es"}}则是加es

对这一段的评论会显示在这里

改进表单

对这一段的评论会显示在这里

同上一章一样,我们先从最为简单、有效的例子开始。 现在我们再来找出这个简单的例子中的不足,然后改进他们。

对这一段的评论会显示在这里

首先,search()视图对于空字符串的处理相当薄弱——仅显示一条”Please submit a search term.”的提示信息。 若用户要重新填写表单必须自行点击“后退”按钮, 这种做法既糟糕又不专业。如果在现实的案例中,我们这样子编写,那么Django的优势将荡然无存。

对这一段的评论会显示在这里

在检测到空字符串时更好的解决方法是重新显示表单,并在表单上面给出错误提示以便用户立刻重新填写。 最简单的实现方法既是添加else分句重新显示表单,代码如下:

对这一段的评论会显示在这里
from django.http import HttpResponse
from django.shortcuts import render_to_response
from mysite.books.models import Book

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

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 render_to_response('search_form.html', {'error': True})**
huangzj 06-16 11:59

else处的**是不是真的要加上去的?

Roger 07-20 02:00

最后一行前后的**明显是排版错误引入的,不应该加入代码。 我猜测这两个*类似于wiki中的加粗作用,但这里没有生效。

酒尽望天 11-08 01:50

为什么我会出现这样的错误提示: Cannot resolve keyword 'title_icontains' into field. Choices are: authors, id, publication_date, publisher, title

CVWEN 11-29 16:00

to 樓上的: 你要 __ 雙底線你應該是打到 _單底線了

匿名读者 03-08 07:10

用utf-8.

Jian 05-27 16:36

**code** **中间的code表示本节新增加的代码。

alex 10-26 07:09

这里的*号我真的不明白用来做什么,作者想表达什么意思阿,为什么要加个**???很简单的事情,搞这么复杂,吃多了吧

llqbll 12-06 03:04

**是字体加粗的意思,不知道问什么一直没改过来?

craigmulux 01-29 13:57

这里的裸机有明显的错误,没有针对books进行判断,换句话说就是是否搜出book,都会返回结果页面下面那个返回到搜索页面不可能到达,更改如下: books = Book.objects.filter (title__icontains = q) if books: return render_to_response ('search_result.html', {'books': books, 'query': q}) else: return render_to_response ('search_form.html', ) else: return render_to_response ('search_form.html', )

cbsw 03-29 09:26

这里不用加双星号**,加了会报错。原英文文档中是粗体显示,此处加*本意是加粗,但估计是没设置好

nothing 04-03 11:01

这里是作者用markdown写的,**表示加粗的意思,只是没有显示被解析成功而已,怎么还有人纠结这事,仔细看下前面的留言也就知道了嘛?

drgcaosheng 08-10 08:25

不是表示新代码就是这样子写的吗?貌似前面几章节有写着.不再对此进行描述.

wangfei 09-03 06:29

同意楼上

syshu 10-14 06:57

'q' in request.GET为真,但是request.GET['q']为假。空字符串为假

zkh 01-22 10:26

from django.shortcuts import render_to_response,render<---- It's important.....zhong wen da buliao QAQ

schin 08-09 05:27

django1.6 网页重定向,可以用 from django.http import HttpResponseRedirect return HttpResponseRedirect('/search-form')

Kazuhira 07-04 08:37

1.9版本也可以使用HttpResponseRedirect 来达成重定向

123 08-25 03:03

为什么这个版本这么垃圾?

Ignora 01-28 07:27

alex真的仔细看过这个教程?前面无脑喷也是你,你吃多了才来看这个的吧。就你这水平还编程?作业做完没?不回去学汉语拼音?

jca 05-30 07:01

楼上真·跨时空对话

对这一段的评论会显示在这里

(注意,将search_form()视图也包含进来以便查看)

对这一段的评论会显示在这里

这段代码里,我们改进来search()视图:在字符串为空时重新显示search_form.html。 并且给这个模板传递了一个变量error,记录着错误提示信息。 现在我们编辑一下search_form.html,检测变量error:

Chika 03-23 01:50

我们来改进

huha 05-12 11:30

我们改进了

gepoe 04-05 09:19

改进来-->改进了

对这一段的评论会显示在这里
<html>
<head>
    <title>Search</title>
</head>
<body>
    **{% if error %}**
        **<p style="color: red;">Please submit a search term.</p>**
    **{% endif %}**
    <form action="/search/" method="get">
        <input type="text" name="q">
        <input type="submit" value="Search">
    </form>
</body>
</html>
duolaimi 09-04 02:30

请教一下,“**{% if error %}** ”此句中的“**”是什么意思?

pengjinyi 11-30 03:28

**表示是新添加的内容

wonder 05-22 06:07

" **表示是新添加的内容 " 是吗?! 这本书不是用 RST 写的吗? **text** 在 RST 里面用来强调(主题显示), 可是在预编辑块里是无效的.

wys 02-01 06:24

空格

jwfy 09-21 09:05

这里的** 不用管是什么意思,只是表示是加粗或者后来标记的意思,让大家注意到这个变化,可能是显示出来出现了问题

Eric6356 10-25 10:21

**应该是MarkDown的语法,表示加粗。这里没有显示成加粗而是把**显示出来了。

QQasdhy 05-12 02:56

这里如果q为一串空格,是否可以q.strip()去除空格再做查询呢,view中怎么实现啊,求大神

mr.liu 08-07 03:04

回复楼上的,如果筛选空格,判断时候可以这样:if 'q' in request.GET and request.GET['q'].strip()

mr.liu 08-07 03:08

如果你搜索字符中加入了空格,数据库查询时候是不会去掉空格的,可以使用这样方法:q = request.GET['q'].strip()

猪头哥哥 12-11 01:13

在这里还要讨论**吗 我滴老天爷

对这一段的评论会显示在这里

我们修改了search_form()视图所使用的模板,因为search_form()视图没有传递error变量,所以在条用search_form视图时不会显示错误信息。

C.J. 07-09 02:43

"条用"应该为"调用"

te 09-22 13:07

也就是说不传递字典的话默认是假或者是空。

对这一段的评论会显示在这里

通过上面的一些修改,现在程序变的好多了,但是现在出现一个问题: 是否有必要专门编写search_form()来显示表单? 按实际情况来说,当一个请求发送至/search/(未包含GET的数据)后将会显示一个空的表单(带有错误信息)。 所以,只要我们改变search()视图:当用户访问/search/并未提交任何数据时就隐藏错误信息,这样就移去search_form()视图以及对应的URLpattern。

zzm88 07-26 06:33

最后一句不好理解,还是看原文:We can remove the search_form() view, along with its associated URLpattern, as long as we change search() to hide the error message when somebody visits /search/ with no GET parameters。

xxoo 07-08 11:22

=_=有时候, 中文确实比英文难理解...

lcczz 02-06 15:40

那也是醉了,英文一目了然,中文看了半天

对这一段的评论会显示在这里
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})
Findhat 11-13 15:14

我觉得这里error变量的初始值应该为True,不然在直接访问/search/的时候是不会提示error信息的。因为直接返回了False啊!我试过了。把第一个error = False改成error = True之后才真正达到了作者需要传达的技巧

pengjinyi 11-30 04:58

第一次访问就应该是不现实错误信息

小邪兽 06-04 08:41

一楼理解有误 1.初始化 error必)点须是False(用于当用户打开search_form时,没有点击submit按钮或刷新页面) 2.判断'q'是否在request.GET字典中,如果在并且'q'的值为空时,证明用户没有提交任何数据却点了submit按钮,此时应重新回到search_form页面,并且置error为True,让它显示错误信息.

xiami 05-14 06:49

为什么最后一个return处没有else呢? 不是和第一个if是并列的么?

andersc 06-25 10:35

@xiami: 如果代码到达了最后一个return,说明q未定义或为空,此时error都为True,会显示错误信息。

alex 10-26 07:11

想问问提交的时候Book无法提交,这事怎么回事?? can't import Book!!!!!!!

silent 11-01 07:31

第一次提交的时候就会显示错误信息,所以算不上一个好的处理方法。

sammy 01-11 09:05

@silent第一次访问就出现错误信息是不是因为你的最后一行不是{'error': error}这个字典 而是{'error': True},这段代码在第一次访问时没有q。error = False.进入search页面时是没有error的,页面不会有错误信息

匿名读者 04-06 08:42

if 'q' in request.GET对应的是刚进入页面,还没有开始搜索的情况

jasper 08-07 07:09

最后一个return不能放在和第一个if对应的else中(就没有这个else),如果没有注意加了这个else,那么导致没有输入的情况下会报错。

特里 09-06 05:47

漏了一段代码,我补上 if not q: error=True return render_to_response('search_form.html',{'error':error})

yinsp 09-25 05:39

提交了之后没反应 是怎么回事?

strof 03-21 08:58

特里说的对

牛三金 04-23 05:45

@特意说错了。原文没错,可以正常执行。

Adamee 05-23 03:16

说的是没错,不过多余了,正确的话会从else里面return,不然的话跳出if从主程序里面return,所以 not q里面不需要return

good job 05-23 07:01

一楼理解有误,二楼理解少对,三楼不会

yu330 06-19 03:22

@good job 说三楼不会,你才没有理解代码意思。

Peter 06-20 03:14

代码应该是这样修改会比较好: (1)在"error = True"的后面再添加一条语句"return render_to_response('search_form.html',{'error':error})" (2)最后一个return,删掉",{'error':error}"

Peter 06-20 06:10

一直弄错了,原来最后一条语句前面没有"else",自己当时主观的加上了

qyhu 06-29 04:13

我觉得不是q的问题,我把books=...这句移到第二个if外面,if not books这样就能在查询不到结果的时候跳转到search_form.html了。

wind 07-26 15:15

@Peter 正确.. 同样躺枪..主观加上了else...

菜鸟 08-30 03:58

提交空关键词又问题,外层else中应该改error值

菜鸟 08-30 03:59

提交空关键词又问题,外层else中应该改error值(看错了)

starof 02-09 06:22

代码正确,各位注意细节。 如果用户访问/search/并且没有带GET数据,那么他将看到一个没有错误信息的表单。(因为error=False,'q' in request.GET为假,直接执行最后一行跳转到search_form.html,且error为假,不显示提示信息); 如果用户提交了一个空表单,他将看到错误提示信息,还有表单;(因为if not q为真,error被置为真,执行最后一行跳转到search_form.html,提示出错i型哪些); 如果用户提交了一个非空值,他将看到出错结果。

123 02-16 15:18

mark

qwe 02-16 15:18

mark

Joseph Daniel 10-29 14:19

mark

WN 03-02 03:20

这样写更好理解,只要把最后一行,放到第二个if里面就好了。 def search(request): error = False if 'q' in request.GET: q = request.GET['q'] if not q: error = True return render_to_response('search_form.html',{'error': error}) else: books = Book.objects.filter(title__icontains=q) return render_to_response('search_results.html', {'books':books, 'query': q})

Belter xin 08-31 02:03

代码没有问题,将第四行改成q = request.GET['q'].strip(),要不然一个空格也能搜索出结果(所有包含空格的记录都会被搜出来)。

YANG WANG 09-01 01:50

代码没有问题 首先访问 /search/的时候request.GET字典中并没有'q',所以初始化error为false 这样search_form才不会有错误提示 当用户第一次按下表单按钮的时候 'q'出现在字典中 然后执行 if 语句里面的东西

xp 08-09 06:41

# 如果request不含'q'这个键,error = False(默认) # 如果request含有'q'这个键,但是q=xxx 后面的xxx为空,error = True return render_to_response('search_form.html',{'error': error})

猪头哥哥 12-11 01:41

这里捋一捋逻辑,这个if是判断url中是否含有‘?q=’这个东西的,如果含有则进行下一步操作 所以这一系列操作都是在if这个分支里的,不管如何最后肯定要render一个东西。所以不存在什么少了else,至于如果有else,意思是不存在'?q=',一般性只会出现在用户手动更改url你可以给个 else: return render(request,'search_from.html')

aaa 01-03 03:21

if not q: 后面少了个return

llxxyy 03-25 08:10

初始化应该为false,这样第一次才不会显示错误信息。真正更改error的情况是在点了提交按钮但是q为空的情况,当q为空,就会执行最后一个return返回error为True的网页。如果q不为空,才返回查找后的网页。

匿名读者 05-14 02:38

感觉很乱,作者的意思应该是这样 def search(request): error = True if 'q' in request.GET and request.GET['q']: q = request.GET['q'] books = Book.objects.filter(title__contains=q) if books: return render_to_response('template/search_request.html',{'books':books,'query':q}) else: return render_to_response('template/search_form.html',{'error':error}) else: error = False return render_to_response('template/search_form.html', {'error': error})

橙子 10-20 12:35

@ Belter xin 大佬的说法正确,原文翻译的代码没有错(只要你别敲错了),再加上大佬Belter xin 所说的 去除空格,则可以筛去空格也能搜索出结果的BUG

对这一段的评论会显示在这里

在改进后的视图中,若用户访问/search/并且没有带有GET数据,那么他将看到一个没有错误信息的表单; 如果用户提交了一个空表单,那么它将看到错误提示信息,还有表单; 最后,若用户提交了一个非空的值,那么他将看到搜索结果。

Michael Meng 08-13 01:38

"若用户访问/search/并且没有带有GET数据,那么他将看到一个没有错误信息的表单; 如果用户提交了一个空表单,那么它将看到错误提示信息,还有表单;"这个没有带GET数据和空表单有什么分别?或者什么情况下触发错误信息提示?

Michael Meng 08-13 01:57

怎么触发的 if no q 这个错误?

michael 11-25 14:49

if not q 代表q是一个空字符串!

Ignora 01-28 08:03

作者的代码没有错误,自己跑一遍就懂了

对这一段的评论会显示在这里

最后,我们再稍微改进一下这个表单,去掉冗余的部分。 既然已经将两个视图与URLs合并起来,/search/视图管理着表单的显示以及结果的显示,那么在search_form.html里表单的action值就没有必要硬编码的指定URL。 原先的代码是这样:

对这一段的评论会显示在这里
<form action="/search/" method="get">
对这一段的评论会显示在这里

现在改成这样:

echo 04-06 09:47

sorry i do not understand

Alex Jason 12-27 13:21

个人理解啊。还望指正: 修改过后的代码是删除了通过search_form来访问表单页面,现在所有访问表单的途径只能通过search方法,同时search方法渲染(加载)搜索结果和搜索表单两个页面,所以即使action=''时候提交表单还是会通过urls.py的路径回到search方法处理表单。action可写可不写。

对这一段的评论会显示在这里
<form action="" method="get">
对这一段的评论会显示在这里

action=”“意味着表单将提交给与当前页面相同的URL。 这样修改之后,如果search()视图不指向其它页面的话,你将不必再修改action

���ϵ 01-09 04:10

���ϵ�绰��13873134385רҵ���ǹ����:��˹�,,������ǹ��ͺӥ�ǹ,����ǹ,���ǹǦ���(4.5MM��.5MM)2��

hoo 04-20 07:55

/search-form/视图 是不是可以删掉了? /search-form/指向的是views.search_form不是views.search

andersc 06-25 10:37

@hoo: 可以删除了,所有的search要从/search/发起了。

lincy 08-17 03:33

不懂这段话啊,谁能解释一下

Aaron 09-24 06:32

一开始search()只负责渲染search_results.html,所以q需要提交到search()进行处理,后来加入了q的相关判断,search()也负责渲染search_form.html。所以另一search_form()自然就不需要。

苏国峰 10-19 14:08

我也没太看懂这句话的意思。估计是说action=“” 就是指当前路径吧,而不是空路径。

lgy 11-12 14:17

是的,可以删掉了,如果不删除掉会报错了

nowkaka 11-22 15:44

如果在Views.py中给Search()函数指定了地址之后,就不需要在模板的form中指定action

timelong 12-16 12:01

action这里不处理,直把/search-form/视图删了,在/search/中操作也可以啊,那么让action="",意义是什么?不懂啊~

DemonKoo 12-22 10:13

@timelong 不去掉当然行,不过人家都说了这里不需要硬编码,去掉冗余而已

herr 02-26 05:11

这里应该是指urls.py里已经指定search了,在硬编码里面就不需要再重复一次再指定了。简单这样理解,不知道对不对。

pyxiaobao 03-03 05:00

我的理解是action=""时候,点击search提交表单时候还是原来(当前)的url,否则假如:action="/xxx/"时,提交表单时候会指向/xxx/这个页面,url会变了。

zsp 04-30 02:13

如果修改成<form action="" method="get"> 那么视图里的search_form(request)就没有必要了,这时候就必须从/search/发起,而不能在从/search-form/发起了

billy 05-22 04:01

最后一句翻译的有点问题,原文“With this change in place, you won’t have to remember to change the action if you ever hook the search() view to another URL” 就是说,可以将action="/search/"改成action="",这样的话,当其他URL需要用到search()的时候,就不需要对search_form.html进行更改了。

billy 05-22 04:22

更正下,不应该是“当其他URL需要用到search()的时候”,是修改search()对应的URL时。

stevenlee87 07-08 10:44

如果再访问/search/的话,也是要加上参数的比如:/search/?q=q

stevenlee87 07-08 10:49

如果再访问/search/的话,也是要加上参数的比如:/search/?q=q sorry。因为我的代码是: return HttpResponse('Please submit a search term.')

heliar 07-19 10:09

action 那个属性是指定点击submit按钮后跳转的页面。留空的意思就是不做跳转,因为views的search函数已经对两种情况都做了分派了。

estar7 08-06 02:29

有點看不太懂。action=""时候,点击search提交表单时候还是原来(当前)的url,只會停留在搜尋頁面,並不會執行 def search(request): 這樣話就不能看到搜尋結果了

Jeff 11-30 17:32

这点非常巧妙,就像只要一条urls配置,达到两个目的。理解到这个点就觉得好有意思。

hehe 08-04 13:35

可能有很多我这样的新手会搞晕掉,这里的意思是原来你需要访问“search_form”去查询数据,现在可以直接访问“search”来查询数据了。因为search既可以渲染search_form,也可以渲染search_results

Aaron 05-24 06:32

楼上正解,action=''之后得再127.0.0.1:8000/search访问了 在从127.0.0.1:8000/search-form访问就会出现提交内容后还是这个页面的问题,所以修改后 就直接通过search访问 views.py里的search_form 也可以删掉了 urls.py里的search_form 路径配置也可以删掉了 只通过 search 访问 但是 search_form.html需要保留

y 09-30 09:31

nice啊,不看评注完全想不到。这样一提醒。确实可以精简很多,相互之间的关系也很明确了

domodo 06-01 02:07

代码亲测,去掉'/search/'后,即使输入正确也无法得到搜索结果了,因为入口还是search,删掉之后就是个在本网页的死循环。

匿名读者 06-25 08:05

还需要修改的是: 1.注释掉urls.py中的“search_form”,只保留"search" url拦截, 2.注释掉views.py中的“search_form()"方法,保留"search()"方法。 OK,此时,search_form 和search 都走"search"的路由-也就是文中提到的action=""时会默认执行url相同的路由。 然后,search方法的逻辑就会根据是否有GET['q']数据来判断render到对应路径。

猪头哥哥 12-11 01:56

这里舍弃了search-from,第一步注释掉url中的search-from一行,第二步吧action改成空的就像上面那样

llxxyy 03-25 12:06

@Aaron说得完全没错

匿名读者 07-19 07:29

@zsp 正解。

xxky 06-10 11:06

action 那个属性是指定点击submit按钮后跳转的页面。留空的意思就是不做跳转,因为views的search函数已经对两种情况都做了分派了。

拉格朗日滴滴 05-03 15:01

这里search页面需要从127.0.0.1:8000/search/进入,而不能从/search-form/进入,即舍弃了search-form,在urls和views中可以删去search-form相关,保留search_form.html,search_form.html和search_results.html都通过search/ 来渲染。

对这一段的评论会显示在这里

简单的验证

对这一段的评论会显示在这里

我们的搜索示例仍然相当地简单,特别从数据验证方面来讲;我们仅仅只验证搜索关键值是否为空。 然后许多HTML表单包含着比检测值是否为空更为复杂的验证。 我们都有在网站上见过类似以下的错误提示信息:

WYM 03-22 15:05

"然后" -> "然而"

snicker 01-16 08:09

然后许多HTML -> 然而许多HTML

对这一段的评论会显示在这里
  • 请输入一个有效的email地址, foo’ 并不是一个有效的e-mail地址。
  • 请输入5位数的U.S 邮政编码, 123并非是一个有效的邮政编码。
  • 请输入YYYY-MM-DD格式的日期。
  • 请输入8位数以上并至少包含一个数字的密码。
对这一段的评论会显示在这里

关于JavaScript验证

mark 07-23 15:39

对这一段的评论会显示在这里

可以使用Javascript在客户端浏览器里对数据进行验证,这些知识已超出本书范围。 要注意: 即使在客户端已经做了验证,但是服务器端仍必须再验证一次。 因为有些用户会将JavaScript关闭掉,并且还有一些怀有恶意的用户会尝试提交非法的数据来探测是否有可以攻击的机会。

蛟龙 08-28 03:57

单纯的javascript页面验证 基本可以退出舞台了

Charles 01-17 04:00

请教一下,页面上做了一个提交按钮,然后用JS写了点击按钮之后页面发生的变化,但是因为提交要调用一个views里的函数,必须返回一个httpresponse,这样页面就被刷新了,JS写的功能也就一闪而过了。请高手指教。

ggoy 11-04 08:42

javascript验证还是必要的,可以减轻服务器压力

brad 03-21 02:52

不懂而楼什么意思。

HankZ 05-31 06:40

@ggoy 2 说的对,可以减轻服务器压力,但是,新手们要知道,通过python,想怎么,就可以怎么提交。

talent 10-09 07:49

要知道,js验证不单单是为了减轻服务器压力,更是为了更好的客户端体验。

111 03-27 06:45

2楼你敢改一下Input的type吗

allen 07-02 03:37

作者说的比较明白了,js端的验证需要存在,用以保证良好的客户体验,同时对提交给服务器端的数据进行验证。同时需要服务器端的验证,防止绕过js验证对服务器端进行攻击。 实际上是js端的单纯验证已经退出了历史了。

对这一段的评论会显示在这里

除了在服务器端对用户提交的数据进行验证(例如在视图里验证),我们没有其他办法。 JavaScript验证可以看作是额外的功能,但不能作为唯一的验证功能。

对这一段的评论会显示在这里

我们来调整一下search()视图,让她能够验证搜索关键词是否小于或等于20个字符。 (为来让例子更为显著,我们假设如果关键词超过20个字符将导致查询十分缓慢)。那么该如何实现呢? 最简单的方式就是将逻辑处理直接嵌入到视图里,就像这样:

tenger13 07-14 01:57

为“来”-->“了”让例子更为显著,

ysyong 12-02 09:14

怎么有人纠错,却没人改错呢?!?!?!?!

对这一段的评论会显示在这里
def search(request):
    error = False
    if 'q' in request.GET:
        q = request.GET['q']
        if not q:
            error = True
        **elif len(q) > 20:**
            **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})
sdsd 10-26 07:03

这里语法错误阿,这个文章错误太多了,运行不起来,很恼火!!!!!!!

llqbll 12-06 03:21

我一直都是和英文原版对照着看,http://www.djangobook.com/en/2.0/chapter07.html

streethacker 07-26 13:17

这里的elif代码块缩进有问题,if/elif/else应该是同层次的。

Aaron 09-24 06:37

**忽略不输入就能运行了

i4oolish 10-28 13:39

查询时候输入汉字会报错,这个怎么解?

allen 07-02 03:40

到目前位置,文章除了翻译,手误和版本问题以外没有任何错误。运行的例子均可通过。djang1.6,python2.7 mysql5.5

mihello 08-10 15:03

最好还是中英对照看,要不各种奇葩问题卡死你

御坂御坂 09-19 04:05

if not q or len(q)>20: error = True 可行?

July 11-05 10:04

to: 御坂妹妹 可行。

funk_T 01-26 10:48

我做到这里没什么问题啊 都挺顺利的 楼上自己搞错了吧

mr.liu 08-07 05:56

在我后面看次篇文章的人,请把英文页对照来看,网址是:http://www.djangobook.com/en/2.0/chapter07.html

te 09-23 07:30

并没有错误啊,django1.9 python2.7 除了版本有些不同以外,其他的内容好好想想就知道了

对这一段的评论会显示在这里

现在,如果尝试着提交一个超过20个字符的搜索关键词,系统不会执行搜索操作,而是显示一条错误提示信息。 但是,search_form.html里的这条提示信息是:”Please submit a search term.”,这显然是错误的, 所以我们需要更精确的提示信息:

对这一段的评论会显示在这里
<html>
<head>
    <title>Search</title>
</head>
<body>
    {% if error %}
        <p style="color: red;">Please submit a search term 20 characters or shorter.</p>
    {% endif %}
    <form action="/search/" method="get">
        <input type="text" name="q">
        <input type="submit" value="Search">
    </form>
</body>
</html>
��� 05-23 04:35

����������ͨ����������������ʱ�վ�����Ķ������Ͻ���������Ļ �߿����13�߿�¼ȡ��-�߿�����2013�߿�����,��ǰ���߷�������а�������-�����- 2013���� �������-���� -2013�������-�������-ȫ���� -2013������� 2013ȫ���� -��������� -�߿�ѧϰ� - 2013�������ǿ -2013�����������-���ҵ�� -������ -���� -����ѧУ -�߿���� -������-�߿����ʱ��-������ -����ϰ - 2013�߿����� -2013���а�� -��� -������ -�����߿�� -����߿�� -�㶫�߿�� -ɽ���߿��- ����߿�� -����߿�� -�����߿�� -����߿�� -�����-���߿�� -����߿�� -�����߿�� -���߿��- ���ո߿�� -���߿��- ����߿�� -����߿�� - ���߿��-����߿��-2013�߿���ϰȫ���.�����������������073178.com����������en.073178.com����������gyu.073178.com����������xiehouyu.073178.com ����������hua.073178.com����������������������������ȵ��ϵ���� �ַ ��www.073178.com//�������/������� 8503

etscript 01-28 15:39

{% if error %}应该是{% if errors %}

gangboy 06-13 01:48

如果error改成errors,判斷式會是false喔

heliar 07-19 12:12

不用改成errors吧。render传进来的参数就是error

对这一段的评论会显示在这里

但像这样修改之后仍有一些问题。 我们包含万象的提示信息很容易使人产生困惑: 提交一个空表单怎么会出现一个关于20个字符限制的提示? 所以,提示信息必须是详细的,明确的,不会产生疑议。

binsen 02-06 08:28

“包含万象”→“包罗万象”

对这一段的评论会显示在这里

问题的实质在于我们只使用来一个布尔类型的变量来检测是否出错,而不是使用一个列表来记录相应的错误信息。 我们需要做如下的调整:

xpp 07-27 06:46

我们只使用了

sai 04-12 03:58

能不能把网友勘误的地方改下

对这一段的评论会显示在这里
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** })
����� 11-26 21:20

�ᄁ���������й�ʱ�������Ч�� �ᄁ�������������������Ԥ��� .���ʱ�� �С�ܵ������������ȾͿ����������tp://shop34608622.taobao.com/ �����������������͸���������ȫ���������������ȫ�֧�֣�֧�������Ƹ�ͨ���ٸ�����ȫ�����������������QQ��635670440 ���ID���ñ���6431 ��ǡ� 1981

golbz 10-23 04:53

这里为什么用数组呢? 变量不是更简单么

匿名读者 04-07 04:54

sadfsdf

andersc 06-25 10:50

@golbz: 看下面的模板,用到了errors和for,这里作者希望展示的是更通用的显示多条错误信息的方法。

匿名读者 08-08 03:22

为什么打**

scarl 08-09 06:05

楼上你看到这里还问这个?

sewe 02-15 06:00

楼上上看到这里还问?打星就是新添加的语句,只是为了显眼。

匿名读者 07-30 15:43

出现错误: Exception Value: The view books.views.search didn't return an HttpResponse object. 代码我都是复制粘贴过来的,实在找不到哪里出错了。 views.search如下: def search(request): def search_form(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 })

匿名读者 07-30 15:46

晕倒,多加了一行 def search_form(request):

Peter 06-20 06:05

"not q"的语句中应该加一句"return render_to_response('search_form.html',{'errors':errors})", "elif"的后面也要加同一句话,这样不会报错

Peter 06-20 06:15

一直弄错了,原来最后一条语句前面没有"else",自己当时主观的加上了。大家注意最后一条语句要与第一个if对齐,要不然会报楼上的错

audax 08-29 05:54

这里error列表里面最多就一个值, 为什么不用变量。

对这一段的评论会显示在这里

接着,我们要修改一下search_form.html模板,现在需要显示一个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>
reax 06-20 10:49

/search/可以不要了

Kevin 06-22 02:15

<form action="/search/" method="get">没有search

zxw 07-25 02:53

这里的/search/应该取消的,否则运行不正确

cal 10-10 07:40

有/search/ 是可以的呀

Linghu 04-03 06:49

看不太懂呀…为什么用列表?用for循环,那有可能一次显示出多个错误提示吗?(列表可能存多个错误提示啊)

Linghu 04-03 06:57

明白了,每次点Search按钮时调用search会重置errors[],列表里最多只存一个值…

helpme 05-21 12:55

如果楼上是正确的,那换别的数据类型行不行啊?set?

Adamee 05-23 03:31

<li style="color: red;">{{ error }}</li> 这样效果也有了, 用list的好处是一次可以传递多个错误信息 比如说 error=['page':'index','info':'too much xxx ','time':'2014-xx-xx'] 就像Django里面debug返回的error应该也是一个数组吧,我只是猜猜,还有,不要在意我的error数组写对了没有,我也是个新手,哈哈

匿名读者 06-18 13:54

去掉/search/的话,就不会显示提示信息里。不会调用view.py中的search方法。

leo 06-18 13:55

去掉/search/的话,就不会显示提示信息里。不会调用view.py中的search方法。

匿名读者 07-10 08:41

越来越高级了!!!!

heliar 07-19 12:22

action不写search亲测可以运行

estar7 08-06 03:31

去掉/search/的话,就不会显示提示信息里。不会调用view.py中的search方法。

mr.liu 08-07 06:11

楼上的请问认真看过么,去掉‘/search/’,表单就会提交给当前使用的url。而你访问表单的url就是http://ip:port/search ,所以去掉‘/search/’无影响。

Aaron 05-24 07:01

action=''之后得再127.0.0.1:8000/search访问了 在从127.0.0.1:8000/search-form访问就会出现提交内容后还是这个页面的问题,所以修改后 就直接通过search访问 views.py里的search_form 也可以删掉了 urls.py里的search_form 路径配置也可以删掉了 只通过 search 访问 但是 search_form.html需要保留

YANG WANG 09-01 02:19

想要产生多个errors 就在search外面 定义一个errors=[]全局变量就行 里面用 global errors访问就行

tangma 10-31 03:54

为什么我的按照教程改了之后,搜索框中为空或者长度大于20都不会报错,都是原界面

stone 03-06 02:47

stone 03-06 02:48

ls字典的键是否修改成了errors(之前是error)

对这一段的评论会显示在这里

编写Contact表单

huanbaojieneng 12-18 03:48

我靠,这节错误太多,根本运行不起来,建议只看不操作

smallevilbeast 01-22 14:56

楼上不知道有木有按照上面的做 我是没有问题的

greeb 05-10 15:36

恩,有小错误,不过基本上是没问题的

gudeng 07-03 09:07

一直走到现在,基本没出问题。小问题也可以搜搜搞定

zxy 07-20 14:45

其实跟着来,解决错误更能提高。 需要的是一点耐心。

xoozi 08-02 01:48

一直跟着做,从来不拷贝代码,都是看明白了再自己脑补着实现,没出过问题。

Aaron 09-24 06:45

不知道抱怨的人怎么想的 人家给你翻译就不错了 小错误自己就不能解决么

lgy 11-12 14:35

对着敲,不懂原理当然会出错了

GragHack 11-13 13:49

Please learn with zeal to django!!

我是东汉帝国伟大的党总书记国家主席及军委主席谁敢逆我? 12-26 08:02

能理解的肯定是没问题的小问题无所谓

楼上好厉害啊! 06-22 05:51

mihello 08-11 13:49

还是强力建议 中英对照看

mr.liu 08-07 06:22

呵呵了,1楼是脑残。不想多说!

MO 10-04 01:33

这部分应该新建一个 app 吧,不能直接像他说的建个包含__init__.py和views.py的文件夹,会有403报错,下面评注大神已解决

te 09-23 07:35

并没有运行不起来,理解了就没有错误了

lize 11-02 09:48

心存感激把,人家翻译也不容易

cccc 07-26 03:34

自学 django 看过别的教程,发现这个教程真的不错,翻译的已经很不错了,模糊的地方可以看看英文。

dsD 03-06 02:50

1楼是自身的问题吧

对这一段的评论会显示在这里

虽然我们一直使用书籍搜索的示例表单,并将起改进的很完美,但是这还是相当的简陋: 只包含一个字段,q。这简单的例子,我们不需要使用Django表单库来处理。 但是复杂一点的表单就需要多方面的处理,我们现在来一下一个较为复杂的例子: 站点联系表单。

objectjava 05-31 02:22

并将其

sunshinepig 09-30 05:46

来一个较为复杂的例子

对这一段的评论会显示在这里

这个表单包括用户提交的反馈信息,一个可选的e-mail回信地址。 当这个表单提交并且数据通过验证后,系统将自动发送一封包含题用户提交的信息的e-mail给站点工作人员。

ode2free 04-10 21:56

系统将自动发送一封包含用户提交信息的e-mail给站点工作人员。

对这一段的评论会显示在这里

我们从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">
        <p>Subject: <input type="text" name="subject"></p>
        <p>Your e-mail (optional): <input type="text" name="email"></p>
        <p>Message: <textarea name="message" rows="10" cols="50"></textarea></p>
        <input type="submit" value="Submit">
    </form>
</body>
</html>
soul_eater 09-02 07:59

出现Forbidden (403)“CSRF verification failed. Request aborted.”的情况,需要添加{% csrf_token %}到form中去,<form action="/contact/" method="post">{% csrf_token %}<p>...</p>...</form> 之后在contact()方法的views.py中添加from django.template import RequestContext并且最后一句改为return render_to_response('contact_form.html',{'errors': errors}, context_instance=RequestContext(request))即可

ysyong 12-02 12:27

楼上威武! 我再来总结一下,共三点。 1.在template中添加{%csrf_token%} 2.在veiws中添加from django.template import RequestContext 3.在views中在render_to_response的最后添加context_instance=RequestContext(request)

ysyong 12-02 12:28

楼上威武! 我再来总结一下,共三点。 1.在template中添加{%csrf_token%} \n 2.在veiws中添加from django.template import RequestContext \n 3.在views中在render_to_response的最后添加context_instance=RequestContext(request) \n

ysyong 12-02 12:29

为什么没有换行格式啊!

atlas 10-02 14:01

没有人发现这里有错误么?/contact/thanks/才正确

benxiang 12-21 06:31

多谢一楼大神

carror 05-14 08:41

感谢1楼大大

whp 07-30 02:48

这个代码表单不显示怎么回事只显示title和h1里的文字,form里的东西只显示submit按钮怎么回事啊,求大神

123 03-05 05:00

http://www.cnblogs.com/Rocky_/p/6140362.html django 1.10 直接使用render(),,才能正确填充token。。。。。

huhu 06-27 04:29

不用这么麻烦,加上{% csrf token %}后,在settings里面,把'django.middleware.csrf.CsrfViewMiddleware'注释掉就行了

Ignora 01-28 10:48

研究了半天,这个Your email也许应该作为邮件正文的一部分发给收信邮箱,以告诉网站管理人员发送者的地址以便他们反馈,否则那个输入框只能填django里面设置的邮箱,填其他邮箱会引发553错误

对这一段的评论会显示在这里

我们定义了三个字段: 主题,e-mail和反馈信息。 除了e-mail字段为可选,其他两个字段都是必填项。 注意,这里我们使用method=”post”而非method=”get”,因为这个表单会有一个服务器端的操作:发送一封e-mail。 并且,我们复制了前一个模板search_form.html中错误信息显示的代码。

对这一段的评论会显示在这里

如果我们顺着上一节编写search()视图的思路,那么一个contact()视图代码应该像这样:

对这一段的评论会显示在这里
from django.core.mail import send_mail
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response

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})
libinBYR 05-18 13:23

报错 CSRF token missing or incorrect settings.py 修改 MIDDLEWARE_CLASSES = () 在最后加上 一条 'django.middleware.csrf.CsrfResponseMiddleware', 模板里面 form 标签后面 贴上 {% csrf_token %}

陈金鑫 09-03 08:15

验证email的语句中的and应该用or

whille 10-29 02:36

验证email的语句中的用or是因为optional,没错

项超 02-08 06:36

根据代码的意思:是使用用户的邮箱给站点邮箱发一份邮件。但是我奇怪django又不不知道用户的邮箱密码,是怎么用用户的邮箱给站点邮箱发邮件的???

donly 03-08 15:41

and 在这用来简单判断email的合法性

donly 03-08 15:43

@项超 并非通过你Email的服务器发送

donly 03-09 08:41

Sorry! https://docs.djangoproject.com/en/dev/topics/email/

chan 03-09 09:35

需要应该是这样:如果提交的email为空,则使用默认的noreply@example.com发送,但如果用户填的是自己的邮箱呢,如何知道用户的邮箱服务器,地址等信息以用来发送。需求是这样吗

weetao 05-06 20:29

return render_to_response('contact_form.html',{'errors':errors},context_instance=RequestContext(request))

weetao 05-06 20:30

from django.shortcuts import RequestContext

keroro 08-30 05:22

回一楼,我的python2.6, django1.4.1 在模板的<form>下加{% csrf_token %} 就可以解决前面的问题了。 而在setting.py里加了那句就会出错。

wq 09-10 08:03

@keroro django1.4.1 不需要{% csrf_token %} ,不需要django.middleware.csrf.CsrfViewMiddleware 。只要在settings.py 中配置好EMAIL_HOST,EMAIL_PORT, EMAIL_HOST_USER ,EMAIL_HOST_PASSWORD ,EMAIL_USE_TLS,即可。亲测,邮件可以发送。

zzcwing 10-17 10:21

errors 是 List结构 django报错,unhashable type: 'list', 这该怎么破?

zzcwing 10-17 10:31

关于:errors 是 List结构 django报错,unhashable type: 'list', 这该怎么破? 我自己找到问题了,这里代码块结尾不应是:{'errors',errors},而应该写成['errors',errors],因为默认是字典传输形式list是可变的不能作为字典的value

Jxl 11-21 21:35

这里说的是网站用网站自己的email发送邮件给管理员,邮件内容包含用户的email地址,所以用户的email是选填的。

Stillwater 12-21 09:27

使用django1.4遇到CRSF报错的,注释掉settings.py文件MIDDLEWARE_CLASSES里面的django.middleware.csrf.CsrfViewMiddleware试试。

leejaen 03-01 04:22

注释settings.py中的#'django.middleware.csrf.CsrfResponseMiddleware',和#'django.middleware.csrf.CsrfViewMiddleware', 在模板中的form里加入的{% csrf_token %}也去掉 1.4.5的解决方法

magnil 03-10 13:03

1.5 按楼上各位办法出现[Errno 111] Connection refused,怎么破?

cheng 04-28 12:54

if request.POST.get('email') and '@' not in request.POST['email']: 这里应该是if not request.POST.get('email') or '@' not in request.POST['email']:-----判断email输入出错的情况

yang 05-30 15:42

我的一提交也出现[Errno 111] Connection refused,问题,有解决的吗?

wdmyong 06-29 09:07

需要对setting.py进行配置,如下: EMAIL_HOST= 'smtp.126.com' EMAIL_PORT= 25 EMAIL_HOST_USER = '@126.com'#你的邮箱 EMAIL_HOST_PASSWORD = '' #你邮箱的密码 #我试过用不存在的邮箱,不行 EMAIL_USE_TLS = True SERVER_EMAIL = EMAIL_HOST_USER DEFAULT_FROM_EMAIL = EMAIL_HOST_USER 在调用send_mail()时,用全参数,默认是用你setting.py中配置的主机邮箱发送邮件。

xxx 07-03 16:17

send_mail方法调用的时候为什么最后要多一个逗号

chu 07-08 13:20

修改send_mail(cd['subject'], cd['message'], '你配置发送的邮箱@xxx.com', [cd.get('email', '如果页面没有提交接收有限就会默认发到此邮箱@xxx.com')],)

chu 07-08 13:21

修改send_mail(cd['subject'], cd['message'], '你配置的发送邮箱@xxx.com', [cd.get('email', '如果页面没有提交邮箱就会默认发到此邮箱@xxx.com')],)

malafish 08-04 00:10

浏览器默认是发送GET请求,大家怎样用火狐浏览器发送POST请求来测试这段代码的?用的插件吗?我知道Poster可以发送POST请求,但是返回的只有是一个消息体内容,并不是网页形式,

lincy 08-17 12:00

....怎么会这么多问题,我是按着英文版的代码,中文版的解释来的,又快又好,没什么问题

jackie 09-16 09:09

有没有人出现这个错误的:A server error occurred. Please contact the administrator.而且没法重定向到contact/thanks啊

Eva 10-12 06:31

error at /contact/ [Errno 10061]

tyroger 10-15 06:55

CSRF token missing or incorrect -- 1 在 templete 中, 为每个 POST form 增加一个 {% csrf_token %} tag. 如下: <form> {% csrf_token %} </form> 2 在 view 中, 使用 django.template.RequestContext 而不是 Context. render_to_response, 默认使用 Context. 需要改成 RequestContext. 导入 class: from django.template import RequestContext 给 render_to_response 增加一个参数: def your_view(request): ... return render_to_response('template.html', your_data, context_instance=RequestContext(request) )

tyroger 10-15 07:34

我觉得这行不对啊,request.POST.get('email', 'noreply@example.com'), 应该直接写死用系统设置邮箱,而把email取值放到邮件正文?反正这个业务理解不了,让用户随便填的话会报错,非法用户。

苏国峰 10-20 15:46

equest.POST.get('email') 发送人地址,一般是需要的,一般需要和smtp验证地址一样。否则smtp服务器报错。电子邮件本来的设计应该是smtp验证和发送人不关联。

打点滴 10-25 09:16

CSRF的解决了。报错Errno 10061 请问怎么解决呀?

karl 11-20 13:47

error 100061

我是涛哥 03-02 13:51

wdmyong 2013-06-29 17:07:55 需要对setting.py进行配置,如下: EMAIL_HOST= 'smtp.126.com' EMAIL_PORT= 25 EMAIL_HOST_USER = '@126.com'#你的邮箱 EMAIL_HOST_PASSWORD = '' #你邮箱的密码 #我试过用不存在的邮箱,不行 EMAIL_USE_TLS = True SERVER_EMAIL = EMAIL_HOST_USER DEFAULT_FROM_EMAIL = EMAIL_HOST_USER 在调用send_mail()时,用全参数,默认是用你setting.py中配置的主机邮箱发送邮件。 这位同学说的对!!我就是按照这个配置方法弄成功的 ,我用的QQ邮箱 ,把‘EMAIL_USE_TLS=TRUE’这句删掉了。 这个发送邮件的功能是, 用户提交表单,如果有邮箱,那么就使用用户的邮箱发送给站点管理人员。 如果用户没有提交邮箱,那么,使用站点邮箱服务器发送邮件给管理人员 。 至于,用户提交的邮箱,为什么不需要密码, ,我也不知道。。毕竟我只是在我的笔记本尝试的,没有邮箱服务器唉。。

haha 03-03 12:52

邮件发给管理人员??管理人员是谁啊,siteowner@example.com要改么?

haha 03-03 13:19

邮件发给管理人员??管理人员是谁啊,siteowner@example.com要改么? 已经试验成功,settings.py里必须要有以下几项: EMAIL_HOST= 'smtp.163.com' EMAIL_PORT= 25 EMAIL_HOST_USER = 'xxxxx@163.com' EMAIL_HOST_PASSWORD = 'xxxxxx' EMAIL_USE_TLS = True DEFAULT_FROM_EMAIL = EMAIL_HOST_USER

haha 03-03 13:51

1.就是and不是or 2.选填的邮箱地址其实就是发送地址,而不是有的人说的接收地址,亲测填settings.py里配置好账号密码的邮箱才能发送成功,或者什么都不填则用settings里默认的邮箱发送,也能成功。填其它邮箱都不会成功,会报SMTPSenderRefused at /contact/错误

jan 03-19 02:36

这一段确实有问题,sedn_mail的第三个参数from_mail是内部的邮件,而不是填在表格里面的邮箱.

Alice 03-20 07:39

sendmail第三个和第四个参数应该互换

trueyao 03-26 07:37

为什么我在表单中填入和系统设置的不一样的邮箱就会报错呢?553, 'Mail from must equal authorized user'

chenzehua 03-27 13:19

[siteowner@example.com],这个邮箱是接收邮件的邮箱,可以是任意一个邮箱。但是,你的发送邮箱即表单页面填写的邮箱则必须要在settings.py中设置好的那个,不然不能发送。如果在settings.py中有DEFAULT_FROM_EMAIL = EMAIL_HOST_USER,则表单页面不填邮箱时也能成功,这时发送邮箱默认为settings.py中设置的邮箱。

Max 04-12 22:22

CSRF token missing or incorrect. http://www.cppblog.com/momoxiao/archive/2011/10/03/157443.html

匿名读者 06-16 08:53

[Errno 110] Connection timed out 怎么解决呢 我用的QQ邮箱 smtp.qq.com对吧

qyhu 07-02 08:22

1.在setting文件中加入对应的mail配置文件(邮件名,stmp,密码等)EMAIL_HOST= 'smtp.126.com' EMAIL_PORT= 25 EMAIL_HOST_USER = '(你的邮箱)' EMAIL_HOST_PASSWORD = '(你的密码)' EMAIL_USE_TLS = True SERVER_EMAIL = EMAIL_HOST_USER DEFAULT_FROM_EMAIL = EMAIL_HOST_USER; 2.在setting文件中middleware_classes注销掉其中的#'django.middleware.csrf.CsrfViewMiddleware'; 3.contact代码中先要导入from django.core.mail import send_mail,其次send_mail函数书写有误,应该为send_mail(request.POST['subject'], request.POST['message'], '(你的邮箱)', [request.POST.get('email')],);修改完后邮件发送成功。

yang 07-03 15:59

A server error occurred. Please contact the administrator.

yang 07-04 13:49

1、setting.py设置: EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = 'smtp.qq.com' EMAIL_PORT = 25 EMAIL_HOST_USER='****@qq.com' EMAIL_HOST_PASSWORD='*****' DEFAULT_FROM_EMAIL = EMAIL_HOST_USER 2、视图代码: send_mail( request.POST['subject'], request.POST['message'], '111@qq.com', [request.POST.get('email')],'111@qq.com') 3、urls.py: (r'^contact/$', contact), (r'^contact/thanks/$', contact), 4、contact_form.html里面加{% csrf_token %}: <form action="/contact/" method="post">{% csrf_token %} <p>Subject: <input type="text" name="subject"></p>

Pegasus 01-26 03:49

https://rayed.com/wordpress/?p=1445 always use render , not render_to_response

pegasus 01-26 09:58

你在settings.py里边配置的是request.POST.get('email', 'noreply@example.com'),这一句的邮件发送服务器,而不是你的站点管理人员的。也就是说,你这里设置的东西是提供给用户用来发邮件用的,但是如果别人留下了自己的的邮箱名又会出现“'mail from address must be same as authorization user' ”的错误,因为别人的邮箱肯定和你settings.py里边设置的不匹配(不要误解使用了用户填的邮箱发送,使用的是你设置的邮件服务器)。后边的siteowner@example.com是可以随便填的接收邮箱,与设置无关。 所以我想这么解决,你随便申请个163邮箱用来给人发邮件,然后第三个参数就默认填这个邮箱,也就是settings.py里边需要设置的。然后把用户留下的email添加到邮件正文里边给你发过去,最后的siteowner@example.com是你用来接受用户反馈的邮箱。 我看到评注里边有说三四参数颠倒的,应该是没有明白settings.py设置的是给用户提供的一个邮件服务器用的,你要是颠倒了的话就让别人随意使用你的邮箱发送了。 .邮箱设置问题。 163默认是开通了smtp的,但是qq没有开通,你需要到qq邮箱账户设置里边开通才可以,要不会出现Authentication failed, please open smtp flag first!'或者 Connection refused等错误。 http://blog.csdn.net/pegasuswang_/article/details/43154535

eross 04-02 01:20

总结一下:1 首先确保163或者qq邮箱的smtp协议开了;2 settings.py里comment掉CSRF(MIDDLEWARE里);3 EMAIL的配置参考楼上,仅注意port如果设置成465(如果你是按照qq邮箱中的方法走,他会建议你设置成465,这样增加安全性),EMAIL_USE_SSL=True. 如果设置成587,EMAIL_USE_TLS=True.

Thibault 05-30 10:08

发送邮件的正确写法应该是。send_mail(request.POST['subject'],request.POST['message'],'siteowner@example.com(这是在setting里面配置过的邮箱,用于发送邮件)',[request.POST('email'), 'receive@example.com'](这两个都是接收邮件的地址,用户填的地址也会收到在表单里面填的内容,有点像是回执。后面一个邮件就是我们用来接收用户所填信息的邮箱),

CC 07-05 03:03

if request.POST.get('email') and '@' not in request.POST['email']: 这里应该用“and”吧,因为: email=0 and not @=0 结果=0,即email不填时,@肯定为空,此时不执行语句 email=1 and not @=1 结果=0,即email不空且@存在,此时不执行语句 email=1 and not @=0 结果=1,即email不空且@不存在,此时执行语句

lyz 12-29 04:13

卡了半天 还是用163邮箱发送成功了(QQ邮箱连接收都接收不了..)。 send_mail( request.POST['subject'], request.POST['message'], request.POST['email'], ['接收信息的邮箱@example.com'], ) EMAIL_USE_SSL = True EMAIL_HOST = 'smtp.example.com' EMAIL_PORT = 465 <- 这个要看你用哪个邮箱 EMAIL_HOST_USER = '发送邮件的邮箱@example.com' EMAIL_HOST_PASSWORD = 'asd123456' <-这个是你开启stmp时候的码(QQ是随机的,163是自定义) DEFAULT_FROM_EMAIL = EMAIL_HOST_USER 墙裂推荐用两个163邮箱收发 记得开启stmp

匿名读者 02-23 12:01

包10061的错,配置setting后开始报错“gaierror at /contact/thanks/ [Errno 11001] getaddrinfo failed”求解

ww 03-20 15:03

[WinError 10061] 由于目标计算机积极拒绝,无法连接。删掉了csrf,成功提交后变成这个了,求大佬解答该怎么解决,环境python3.6,django2.0.3

llxxyy 03-25 12:31

这是有邮箱但是又想不合法的验证。因为这个需求是邮箱为空也可以

ccc 11-13 08:47

[WinError 10060] 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。

对这一段的评论会显示在这里

(如果按照书中的示例做下来,这这里可能乎产生一个疑问:contact()视图是否要放在books/views.py这个文件里。 但是contact()视图与books应用没有任何关联,那么这个视图应该可以放在别的地方? 这毫无紧要,只要在URLconf里正确设置URL与视图之间的映射,Django会正确处理的。 笔者个人喜欢创建一个contact的文件夹,与books文件夹同级。这个文件夹中包括空的__init__.py和views.py两个文件。

Hanson 07-23 05:50

pengyao 11-02 07:03

“这这里”应为“这里” “可能乎”还是直接“可能比较好”

pzpz 03-13 03:35

这毫无紧要 应改成 这无关紧要

lincy 08-17 11:54

新建contact文件夹后,在urls里面就会同时出现两个views,一个是books的,一个是contact的。。。。

lincy 08-17 12:02

上文提到的问题的解决办法是:import books.views import contact.views

dagger 08-29 05:15

@ls ,报错了No module named contact.views,contact文件夹和books和mysite/mysite在同一级,在mysite/下

coco 09-06 13:16

@ls 你在调用的时候不要弄错了 (r'^search/$', books.views.search), (r'^contact/thanks/$',contact.views.contact) 两个Views调用里面的函数时,加上文件路径啊

sanyang 01-01 08:16

@dagger 检查你添加的__init__.py是否拼错,我的写成了__int__.py,怎么排错都不行,差点要疯掉了。。。 Solution: Add an empty __init__.py file under the contact folder 原因: The __init__.py files are required to make Python treat the directories as containing packages; this is done to prevent directories with a common name, such as string, from unintentionally hiding valid modules that occur later on the module search path. In the simplest case, __init__.py can just be an empty file, but it can also execute initialization code for the package or set the __all__ variable, described later. (See: http://docs.python.org/tutorial/modules.html)

good job 05-23 08:13

一楼理解有误,二楼理解少对,三楼不会

allen 07-02 06:08

from django.conf.urls import patterns, include, url from mysite.views import current_datetime from books.views import * from contact.views import * from django.contrib import admin admin.autodiscover() urlpatterns = patterns('', # Examples: # url(r'^$', 'mysite.views.home', name='home'), # url(r'^blog/', include('blog.urls')), url(r'^admin/', include(admin.site.urls)), url(r'^time/?$', current_datetime), # url(r'^books/$', include(books.urls)), ) urlpatterns += patterns('books.views', url(r'^request/?$', display_meta), url(r'^search_form/?$', search_form), url(r'^search/?$', search), ) urlpatterns += patterns('contact.views', url(r'^contact/?$', contact), ) django1.6

snowfly 08-13 02:28

views同名了 会被覆盖 我是用起别名解决的 from books import views as views_1 from contact import views as views_2

匿名读者 09-23 15:26

新建文件夹后直接这样引入就行了,如下: from books.views import search, search_form from contact.views import contact

冯日 11-07 08:01

from django.views.decorators.csrf import csrf_exempt @csrf_exempt def contact(request):

Goddamnchen 09-14 03:35

此处如果还想在新建的contact文件夹下设置一个新的templates文件夹,并且将contact_form.html挪到contact/templates下,需要在settings中的INSTALLED_APPS下添加contact条目。否则django无法查找到你新建的templates文件夹下的模板

kenny 01-13 15:19

此处为什么不 startapp 呢?手动建立文件夹是什么意思?也可以起作用吗?

对这一段的评论会显示在这里

现在来分析一下以上的代码:

对这一段的评论会显示在这里

确认request.method的值是’POST’。用户浏览表单时这个值并不存在,当且仅当表单被提交时这个值才出现。 (在后面的例子中,request.method将会设置为’GET’,因为在普通的网页浏览中,浏览器都使用GET,而非POST)。判断request.method的值很好地帮助我们将表单显示与表单处理隔离开来。

te 09-24 12:50

什么时候使用get什么时候使用post?是不是一般在提交数据的时候,对数据库进行操作的时候使用post,其他一般情况比如传递某个参数服务器只是计算一下就返回的是不是就用get?

Lionel.Shen 10-14 06:40

我觉得是不是所有的表单处理都应该用post啊,post更安全一点。

对这一段的评论会显示在这里

我们使用request.POST代替request.GET来获取提交过来的数据。 这是必须的,因为contact_form.html里表单使用的是method=”post”。如果在视图里通过POST获取数据,那么request.GET将为空。

Labi Kyo 11-02 08:35

method=”post” => method="post"

horizonshd 09-15 07:10

如果在视图里通过POST获取数据,那么request.GET将为空。==> 如果在视图里通过GET获取数据,那么request.GET将为空。

对这一段的评论会显示在这里

这里,有两个必填项,subject 和 message,所以需要对这两个进行验证。 注意,我们使用request.POST.get()方法,并提供一个空的字符串作为默认值;这个方法很好的解决了键丢失与空数据问题。

zbyzhlsp 12-09 14:57

关于request.post.get(),参考此页面 http://groups.google.com/group/django-users/browse_thread/thread/870acaba1172e468

goog 06-13 01:09

'' ,那不是总没有错误?

lgy 11-13 02:01

建议ls好好学学 python

elvis 03-29 08:40

使用request.POST.get()方法 可以获取表单指定键的值内容 并可以在获取表单内容的同时提供一个默认值防止该键对应的值为空.例如从post中取得数据,如果不存在则默认值为1 pageNumber = request.POST.get('pageNumber',1)

蜗牛 01-07 01:44

elvis 解决困惑

ww shuai 03-21 12:34

lss说的好

xxky 06-11 07:02

使用request.POST.get()方法 可以获取表单指定键的值内容 并可以在获取表单内容的同时提供一个默认值防止该键对应的值为空.例如从post中取得数据,如果不存在则默认值为1 pageNumber = request.POST.get('pageNumber',1)

对这一段的评论会显示在这里

虽然email非必填项,但如果有提交她的值则我们也需进行验证。 我们的验证算法相当的薄弱,仅验证值是否包含@字符。 在实际应用中,需要更为健壮的验证机制(Django提供这些验证机制,稍候我们就会看到)。

徐浣泽 01-09 02:57

稍候 -> 稍后

Stillwater 12-21 09:38

发送邮件配置(仅供新手参考):在settings.py最后添加EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = 'smtp.qq.com' EMAIL_PORT = 25 EMAIL_HOST_USER = '你的QQ邮箱账号' EMAIL_HOST_PASSWORD = '你的QQ邮箱密码'

Tony 08-23 07:46

如果使用公司内部的smtp服务器,只需要在settings文件中添加EMAIL_HOST,EMAIL_PORT即可,不需要邮箱的用户名和密码一样可以发送。

Eva 10-12 06:41

Page not found (404) Request Method: GET Request URL: http://localhost:1643/contact/thanks/ 这错误要怎么解决啊

Wood 10-12 07:13

邮件成功发送,但上管理员邮箱却没找到新邮件,为何??

i4oolish 10-28 15:21

501, 'mail from address must be same as authorization user' 怎么破解??

vvv 12-04 05:33

我也是:501, 'mail from address must be same as authorization user' 怎么破解??

skyler 12-30 15:46

thar port is already in use

牛三金 04-23 08:27

'mail from address must be same as authorization user'的意思是,SMTP服务器要求你发送人与发送邮箱要一致。也就是说,不能用自己邮箱的SMTP来发送不以自己EMAIL地址为发送人的邮件。很拗口,琢磨一下。

mihello 08-11 14:34

使用外部邮箱 例如gmail 可以参考: http://www.i-alive.com/post/23/

对这一段的评论会显示在这里

我们使用了django.core.mail.send_mail函数来发送e-mail。 这个函数有四个必选参数: 主题,正文,寄信人和收件人列表。 send_mail是Django的EmailMessage类的一个方便的包装,EmailMessage类提供了更高级的方法,比如附件,多部分邮件,以及对于邮件头部的完整控制。

lgy 11-13 02:03

mark

虎头蔓 01-13 08:03

SMTPAuthenticationError at /contact/ (550, '\xd3\xc3\xbb\xa7\xb1\xbb\xcb\xf8\xb6\xa8') 求解~!!

对这一段的评论会显示在这里

注意,若要使用send_mail()函数来发送邮件,那么服务器需要配置成能够对外发送邮件,并且在Django中设置出站服务器地址。 参见规范:http://docs.djangoproject.com/en/dev/topics/email/

匿名读者 04-15 03:27

此处给本机应该如何配置

te 09-24 13:04

看这个http://www.ziqiangxuetang.com/django/django-send-email.html,一般就可以发送邮件了,我是照着这个做的,django1.9,发送成功,不过建议还是看看官网的讲解。

对这一段的评论会显示在这里

当邮件发送成功之后,我们使用HttpResponseRedirect对象将网页重定向至一个包含成功信息的页面。 包含成功信息的页面这里留给读者去编写(很简单 一个视图/URL映射/一份模板即可),但是我们要解释一下为何重定向至新的页面,而不是在模板中直接调用render_to_response()来输出。

Rain 12-13 08:30

很简单 一个视图/URL映射/一份模板即可 ---- shui xie le ? ...how to code ? who can give an eg. ...

Stillwater 12-21 09:34

懒得做的话直接跳转到以前做的任意一个视图不就行了...

atlas 10-02 14:55

添加一个模板,名字叫thanks.html,内容是<h1>Congratulations, e-mail sent successfully!!!</h1> 然后添加一个视图函数,在原来contact下的views.py里面加上如下内容:def thanks(request): return render_to_response('thanks.html',{}). 配置url,添加(r'^contact/thanks/$',thanks),记得导入thanks这个函数,然后发送邮件成功后就会跳转到你指定的页面

love 03-15 14:10

from django.views.generic import TemplateView 可以直接在url.py指向Template啊 url(r'^contact/thanks/$',TemplateView.as_view(template_name='thanks.html'))

ddian 10-27 10:29

其实大家可以看看webpy 我觉得那个比较简单,但是需要自己做的东西较多

对这一段的评论会显示在这里

原因就是: 若用户刷新一个包含POST表单的页面,那么请求将会重新发送造成重复。 这通常会造成非期望的结果,比如说重复的数据库记录;在我们的例子中,将导致发送两封同样的邮件。 如果用户在POST表单之后被重定向至另外的页面,就不会造成重复的请求了。

sdf 06-30 13:02

s

test 06-30 13:02

test

good 03-05 03:57

好手段,学习了

千里山南 01-05 03:17

这种做法貌似也解决不了邮件重复发送的问题吧?

jwfy 02-20 08:15

这个不错,可我感觉即使刷新了,但是不点击提交提交数据还是不会发送数据的吧

heliar 07-19 13:17

更复杂的一般会设置成页面已过期什么的。。估计那个有效时间控制成一两分钟。

kidy 12-09 05:34

这一块地方我看不懂了,希望哪些大神能好好解释一下

mr.liu 08-07 09:38

我就本链接显示的,没重定向....刷新了,表单就清空了,没有提交到服务器啊。

电饭锅 02-10 10:36

感觉这里可能写得是有点问题,刷新应该不会提交表单信息的

对这一段的评论会显示在这里

我们应每次都给成功的POST请求做重定向。 这就是web开发的最佳实践。

lgy 11-13 02:13

mark

Good 07-28 00:46

shabio 10-13 03:55

她是它,它是她

对这一段的评论会显示在这里

contact()视图可以正常工作,但是她的验证功能有些复杂。 想象一下假如一个表单包含一打字段,我们真的将必须去编写每个域对应的if判断语句?

对这一段的评论会显示在这里

另外一个问题是表单的重新显示。若数据验证失败后,返回客户端的表单中各字段最好是填有原来提交的数据,以便用户查看哪里出现错误(用户也不需再次填写正确的字段值)。 我们可以手动地将原来的提交数据返回给模板,并且必须编辑HTML里的各字段来填充原来的值。

qing 02-18 04:18

`'noreply@example.com`_' --> 'noreply@example.com' 应该是这样吧 还有这个 `'siteowner@example.com`_'

wcl 10-20 14:48

就有这问题

对这一段的评论会显示在这里
# views.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', `'noreply@example.com`_'),
                [`'siteowner@example.com`_'],
            )
            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', ''),**
    })

# 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">
        <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>
qing 02-18 04:20

`'noreply@example.com`_' --> 'noreply@example.com' 应该是这样吧 还有这个 `'siteowner@example.com`_'

wynner 10-14 07:44

使用post会报错如下,使用GET就正常了,为什么? Forbidden (403) CSRF verification failed. Request aborted. Help Reason given for failure: CSRF token missing or incorrect. In general, this can occur when there is a genuine Cross Site Request Forgery, or when Django's CSRF mechanism has not been used correctly. For POST forms, you need to ensure: The view function uses RequestContext for the template, instead of Context. In the template, there is a {% csrf_token %} template tag inside each POST form that targets an internal URL. If you are not using CsrfViewMiddleware, then you must use csrf_protect on any views that use the csrf_token template tag, as well as those that accept the POST data. You're seeing the help section of this page because you have DEBUG = True in your Django settings file. Change that to False, and only the initial error message will be displayed. You can customize this page using the CSRF_FAILURE_VIEW setting.

wynner 10-14 08:12

在网上找了一些解决方案,其中比较方便的一个是在settings.py里面的MIDDLEWARE_CLASSES 中加入'django.middleware.csrf.CsrfResponseMiddleware', 错误就消除了。

xwb1989 12-31 06:50

@wynner 我这儿貌似没用..依然403

xwb1989 12-31 07:03

@wynner 解决了,需要在setting.py里添加: 'django.middleware.csrf.CsrfViewMiddleware', 'django.middleware.csrf.CsrfResponseMiddleware',

xiami 05-15 06:18

@wynner你的django什么版本的,我在settings.py里的MIDDLEWARE_CLASSES 中加入'django.middleware.csrf.CsrfResponseMiddleware', 会引发server problem,网上搜说django1.3以后没有这个类。可是Forbidden (403) CSRF verification failed. Request aborted. 的问题还是一直在的。有没有解决方案?

douya 08-06 07:19

@xiami,我是1.4的,也不能添加django.middleware.csrf.CsrfResponseMiddleware 有什么办法解决吗

sdsd 10-26 07:02

这里语法错误阿,这个文章错误太多了,运行不起来,很恼火!!!!!!!

alex 10-26 07:14

这里语法错误, ''noreply@example.com'_')同下 错误

Stillwater 12-21 09:50

1.4的,注释掉'django.middleware.csrf.CsrfViewMiddleware'

Chris 01-28 07:29

这些代码看看就行了,没必要运行。 学习后面的forms

cheng 04-28 13:09

'django.middleware.csrf.CsrfResponseMiddleware',---在setting里注释掉这个---然后会出错时因为文章的代码有逻辑错误: if request.POST.get('email') and '@' not in request.POST['email']: 这里应该是if not request.POST.get('email') or '@' not in request.POST['email']:-----判断email输入出错的情况

angus 07-17 07:21

楼上别误导被人,email的校验没错,是可以为空的

hekun 07-31 01:26

我的这行 request.POST.get('email', `noreply@example.com') 有语法错误啊。

匿名读者 08-08 06:51

email的判断没有错 楼上的你的引号错了

lincy 08-17 12:12

额,我建议碰到错误比较多的章节,可以看英文版的代码,看中文版的解释,或者直接全看英文版(这样速度会慢点)我就是用前者,没遇到什么问题,对楼上各位深表同情,加油!

benxiang 12-21 06:48

代码中两边的**是干什么的。。。小白

fly2fire 02-26 15:21

Forbidden (403) CSRF verification failed. django 1.4下, 1,修改template文件 <form action="/contact/" method="post">{% csrf_token %} 2,修改view文件 a,import RequestContext from django.template import RequestContext b,最后一行改成 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))

Max 04-14 04:10

请对照英文的看 http://www.djangobook.com/en/2.0/chapter07.html

Adamee 05-23 05:59

error at /contact/ [Errno 10061] 我觉得先pass他

xon 06-30 14:18

例子的写法太啰嗦了,1.5后应该有更简单的方法了,看来还得继续研究新的官方文档

dexter 07-02 05:54

我用的是1.6版本,CSRF 卡了我一个中午,最终是看这篇博文解决的http://blog.csdn.net/tr1ue/article/details/20654943

wind 07-08 15:43

=_= 打好Python基础, 就会看得轻松无比...看得轻松无比, 就无需太多脑补...无需太多脑补, 就不会抛出太多异常

yoncan 08-14 11:01

如果是403,注释此项即可 #'django.middleware.csrf.CsrfViewMiddleware', > 最终的如下 MIDDLEWARE_CLASSES = ( 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.locale.LocaleMiddleware', 'django.middleware.common.CommonMiddleware', #'django.middleware.csrf.CsrfViewMiddleware', # 'django.middleware.csrf.CsrfResponseMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', )

syshu 10-15 05:16

@dexter 是对的。 搞了半天才发现不能写{...}.update(csrf(request)) 必须c={...}然后c.update(csrf(request)) 大概是因为update()不返回引用

misutt 10-20 08:04

Σ( ° △ °|||)︴快被这几段代码搞疯时,注释掉 'django.middleware.common.CommonMiddleware',和 'django.middleware.csrf.CsrfViewMiddleware',就成功了,……(╯‵□′)╯︵┻━┻

灰灰 10-29 05:18

这段代码很短,但是真心发现python写的非常的漂亮.我发现我爱上django了

小拿 03-11 07:33

注释掉'django.middleware.csrf.CsrfViewMiddleware',就没有CSRF验证错误了

XRTDKR 05-13 12:15

1.7版本中会提示使用四种方法去解决这个问题:分别是在表单中添加{% csrf_token %},......最重要的是在render_to_response()的时候加上一个requestContext参数,如: return render_to_response('back.html', {'have': have, 'error1': error1, }, context_instance=RequestContext(request))

Junco 06-14 12:50

render_to_response默认使用的是Context, 需要在其中显式指定context_instance=RequestContext

zoro 09-27 02:03

注释掉csrf验证 用qq邮箱不成功 用163就行了...

qwe 01-20 06:22

orbidden (403) CSRF verification failed. django 1.4下, 1,修改template文件 <form action="/contact/" method="post">{% csrf_token %} 2,修改view文件 a,import RequestContext from django.template import RequestContext b,最后一行改成 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))

lvze 09-24 04:00

@fly2fire 正解,已经运行成功。还需要注意的是这是发送邮件,需要在settings文件中进行邮件配置

yorun 05-26 09:08

if request.POST.get('email') and '@' not in request.POST['email']: 我的理解,email不为空且没有@,if为True error执行。 如果用or,request.POST.get('email'),email不为空,if为True,error为空,也就是说只要你输入就会error,显然是不合理的。

匿名读者 05-15 02:36

python3 django2 def contact(request): error = Error() if request.method == 'POST': if not request.POST.get('subject',''): error.set_su_value("Enter a subject") if not request.POST.get('message', ''): error.set_mess_value("Enter a message.") if not request.POST.get('email') or '@' not in request.POST['email']: error.set_email_value("Enter a valid e-mail address.") if error.mess_value and error.su_value and error.email_value is None: send_mail( request.POST['subject'], request.POST['message'], EMAIL_HOST_USER, [request.POST['email'],], ) return HttpResponseRedirect('/contact/thanks/') else: return render_to_response('template/contact_form.html', {'errors': error, 'subject':request.POST.get('subject',''), 'message': request.POST.get('message',''), 'email': request.POST.get('email',''), },) else: return render_to_response('template/contact_form.html',{'errors': error}) <!DOCTYPE html> <html lang="en"> <head> <title>Contact us</title> </head> <body> <h1>Contact us</h1> <form action="/contact/" method="post"> {% csrf_token %} <p>Subject: <input type="text" name="subject" value={{subject}}> {% if errors.su_value%} {{errors.su_value}} {% endif %} </p> <p>Your e-mail (optional): <input type="text" name="email" value={{ email }}> {% if errors.email_value%} {{errors.email_value}} {% endif %} </p> <p>Message: <textarea name="message" rows="10" cols="60">{{message}}</textarea> {% if errors.mess_value%} {{errors.mess_value}} {% endif %} </p> <i

电饭锅 02-10 06:20

加了csrf验证后提交表单又出现 [WinError 10061] 由于目标计算机积极拒绝,无法连接。 又是怎么回事

对这一段的评论会显示在这里

这看起来杂乱,且写的时候容易出错。 希望你开始明白使用高级库的用意——负责处理表单及相关校验任务。

对这一段的评论会显示在这里

第一个Form类

对这一段的评论会显示在这里

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

对这一段的评论会显示在这里

Django的newforms库

对这一段的评论会显示在这里

在Django社区上会经常看到django.newforms这个词语。当人们讨论django.newforms,其实就是我们本章里面介绍的django.forms。

��� 11-11 00:18

��һ�ҷ��Ϣ�. DZ��һ�ҷ��Ϣ�. ��һ�ҷ��Ϣ�. ����ҷ��Ϣ�. ��һ�ҷ��Ϣ�. ����ҷ��Ϣ�. ���һ�ҷ��Ϣ�. �����Ϣ�. ʮ�һ�ҷ��Ϣ�. ��һ�ҷ��Ϣ�. ���һ�ҷ��Ϣ�. �Ƹ���ҷ��Ϣ�. ���һ�ҷ��Ϣ�. ���һ�ҷ��Ϣ�. ���һ�ҷ��Ϣ�. �ˮһ�ҷ��Ϣ�. ̨�һ�ҷ��Ϣ�. ���һ�ҷ��Ϣ�. �ɽһ�ҷ��Ϣ�. ����ҷ��Ϣ�. ����ҷ��Ϣ�. ��һ�ҷ��Ϣ�. ���һ�ҷ��Ϣ�. ��һ�ҷ��Ϣ�. �����ҷ��Ϣ�. ���һ�ҷ��Ϣ����Ҫ�Ŀ������������������ת����ְ���Ƹ�������ѵ���ҽ̡��������������ά���װ������������ҽ�����顢�����������������������ҵ����ȡ� ��ӭ���ѷ��Ϣ����ѹ� http://www.1jfl.com http://www.1jfl.cn http://www.1jfl.com.cn һ�ҷ��Ϣ� 5130

好孩子 01-06 07:31

乱码了

smileMoo 01-24 08:27

慌张了...

zzm88 07-31 03:23

广告。。

estar7 08-06 07:03

或許裡面有藏著重大秘密!!

misutt 10-20 08:07

好奇为什么会乱码

冯日 11-07 08:10

我翻译一下,大概的意思是,我很帅,我很棒,我就是天才

jasper 07-08 09:00

这里不得不解释一下,楼上说的’我‘正是在下....

08-24 07:17

Belter xin 08-31 06:55

O(∩_∩)O哈哈~

本人著 09-21 19:21

2333

刘家乐 02-10 10:48

没错,在下正是大帅比

a 12-22 06:55

aa

a<b>b</b> 12-22 06:55

aa<b>b</b>

对这一段的评论会显示在这里

改名其实有历史原因的。 当Django一次向公众发行时,它有一个复杂难懂的表单系统:django.forms。后来它被完全重写了,新的版本改叫作:django.newforms,这样人们还可以通过名称,使用旧版本。 当Django 1.0发布时,旧版本django.forms就不再使用了,而django.newforms也终于可以名正言顺的叫做:django.forms

nathan 11-19 05:45

当Django第一次

ysyong 12-02 12:55

哈哈哈哈,好有意思啊!!!

smileMoo 01-24 08:28

每当听到第一次怎么老是邪恶?

lincy 08-17 12:28

ls你太邪恶了,连Django都不放过

coco 09-08 02:11

哎呀呀!一群寂寞的程序猿啊!!我了个擦擦!都没有过第一次的经历么。。。好吧,可耻的匿了。。。

vvv 12-04 01:45

现在编程的都这么猥琐了么

yyyee 12-13 06:08

哈哈, 我也是的啊,还没第一次。怎么办 ?

jwfy 02-20 08:34

这感觉不科学啊,不应该是左右手么?

说没有第一次的左右酱在悲伤的看着你`(*∩_∩*)′ 03-07 09:05

wind 07-08 16:10

ls的猿猿都好下流, 看看lx的MM都不好意思了..o(^v^)o

heliar 07-19 15:35

哈哈哈这都能联想到真是佩服楼上的

misutt 10-20 08:12

LS们不忍直视呀^_^

第一次,你给了谁,投票:1、手 2、表妹3、妓女4、老婆5、女朋友6、陌生人7、自然遗了 11-07 08:12

wuwuwu 01-27 08:52

我也没有第一次 好害怕受歧视 呜呜~~~~(>_<)~~~~

guccang 08-14 08:00

....确实寂寞。这是已知的最好的,django教程。没有之一。NB

匿名读者 09-09 05:41

左手

leo 11-10 07:28

上一次还是四年前,自从学了python~

浙理包晓安丧尽天良 11-26 11:43

看了楼上的评论,老泪纵横,赶紧去P站平复净化一下心灵

电饭锅 02-10 10:52

想找个女朋友做一次

对这一段的评论会显示在这里

表单框架最主要的用法是,为每一个将要处理的HTML的<Form> 定义一个Form类。 在这个例子中,我们只有一个<Form> ,因此我们只需定义一个Form类。 这个类可以存在于任何地方,甚至直接写在views.py 文件里也行,但是社区的惯例是把Form类都放到一个文件中:forms.py。在存放views.py 的目录中,创建这个文件,然后输入:

ok 05-10 07:27

forms.py存放在views.py目录是在建好了contact目录下?还是主目录下?2个都得试试看....

zorro 06-21 02:22

一开始也没看懂,但是联系上文,明白说的是/contact目录下,我是直接新建了一个contact app,然后在里面的views.py添加了def contact方法,同理在contact目录下,新建forms.py类

xxsrobin 07-13 01:58

用类来定义表单,revo

匿名读者 12-12 09:03

使用forms框架是为你处理的每一个html <form>标签定义一个Form类。在本例中,我们只有一个<form>,所以只定义一个Form类就行了。只要你愿意,这个类你放哪都成————比如说view.py文件里。但是社区的惯例是把Form类放到一个单独的文件中:forms.py。在存放view.py的目录创建这个文件,然后输入:

jstech 07-05 03:41

这里,和struts1惊人的相似。这个后台表单单纯的用来,接收数据与数据验证,我似乎可以自定义验证函数,例如验证中国的省份证号码

jstech 07-05 03:47

不过更有趣是,他能提供在前台显示:{{ form.as_table }}。

misutt 10-20 08:19

看到有这种方式真好……

wan ze 01-30 04:14

类似于.net mvc中的viewmodel

对这一段的评论会显示在这里
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

nofree 04-12 01:15

“并且很像在模块”应为“并且很像在模型”吧

jawatang 07-24 06:46

[quote]按照惯例,把form类都放在一个文件中[quote] 这里只是说放在一个文件(froms.py)中,没有强调是一个单独的文件夹。所以出现的问题就是下面的import无法执行。如果还是处于books目录下的话。(从第一章看到第七章的用户),应该执行:from mysite.books.forms import ContactForm

image72 08-10 09:32

>>> 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} ContactForm({subject': Hello, email: adrian@example.com, message: Nice site!})中缺少一个单引号.

image72 08-10 09:34

>>> 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} ContactForm({subject': Hello, email: adrian@example.com, message: Nice site!})中缺少很多个单引号.

1 12-22 09:27

4

对这一段的评论会显示在这里

让我们钻研到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_subject" /></td></tr>
<tr><th><label for="id_email">Email:</label></th><td><input type="text" name="email" id="id_email" /></td></tr>
<tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr>
ode2free 04-11 18:28

from mysite.contact.forms import ContactForm 假设在contact文件夹下

ode2free 04-11 19:37

chrome 代码显示不全,应该如下: >>> 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_subject" /></td> </tr> <tr> <th><label for="id_email">Email:</label></th> <td><input type="text" name="email" id="id_email" /></td> </tr> <tr> <th><label for="id_message">Message:</label></th> <td><input type="text" name="message" id="id_message" /></td> </tr>

ode2free 04-11 19:38

没办法断行。。。。

shrek82 04-25 07:06

“让我们钻研到Python解释器里面看看这个类做了些什么” 请问是则么进入到Python解释器里执行呢? 我是在doc下进入该项目文件夹,然后执行 >>from contact.forms import ContactForm 显示有错误。

ode2free 04-30 07:31

@shrek82 用这个命令 python manage.py shell 可以调入相应的settings

kein 09-29 06:19

应该是直接在python IDE中定义class ContactForm() 然后f=ContactForm() print f 在manage.py shell下从form.py中import ContactForm失败

jusshark 10-03 11:13

我知道了,如果在contact的文件夹下新建一个空白的文件__init__.py,那么就不会出现导入出错的错误了(ImportError: No module named contact.forms)

itGuo 06-09 08:26

from django.conf import settings settings.configure() #添加这两句才不会报错

maxiaolei 06-19 07:22

from books.models import Book

maxiaolei 06-19 07:23

from books.models import ContactForm 上一条打错了

Tarivs 07-16 12:26

新建了一个APP:contact 在Pycharm终端里面输入: D:\python\mysite>python manage.py shell Python 2.7.6 (default, Nov 10 2013, 19:24:18) [MSC v.1500 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. (InteractiveConsole) >>> 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="text" /></td></tr> <tr><th><label for="id_message">Message:</label></th><td><input id="id_message" name="message" type="text" /></td></tr> >>>

seakia 11-18 05:24

如果是把forms.py放在books文件夹下的话,直接from books.forms import ContactForm即可,因为是在mysite这个文件夹下进入shell的。

杜浩 05-25 05:45

如果是把forms.py放到一个文件夹里面,那么想访问的时候文件夹里面一定要有__init__.py文件 这样才可以使用 from 文件夹名.forms import ContactForm

Belter xin 08-31 07:20

用python manage.py shell 进入python shell命令行

对这一段的评论会显示在这里

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

对这一段的评论会显示在这里

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

对这一段的评论会显示在这里
>>> print f.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 f.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>
maxiaolei 06-19 07:22

from books.models import ContactForm

stevenlee87 07-15 08:39

ls的打错了。 应该是from contact.forms import ContactForm

xu 10-26 09:20

这里能有怎么样的作用?对于表单输入不用再敲代码了!!!

不满 06-27 08:49

我感觉是增加了灵活性,一会ul,一会p,可以随意切换

对这一段的评论会显示在这里

请注意,标签

    的开闭合标记没有包含于输出当中,这样你就可以添加额外的行或者自定义格式。

    对这一段的评论会显示在这里

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

    mr.liu 08-11 02:11

    便于字段单独渲染

    chg_self 07-17 02:20

    f['subject']感觉使用f.subject 更好一点

    对这一段的评论会显示在这里
    >>> print f['subject']
    <input type="text" name="subject" id="id_subject" />
    >>> print f['message']
    <input type="text" name="message" id="id_message" />
    对这一段的评论会显示在这里

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

    qing 02-18 05:24

    我们创建一个新的对Form象 -->我们创建一个新的Form对象

    duolaimi 06-22 07:24

    请教,为什么不是f.subject或f.message?

    沈世军 10-21 02:28

    这里可以推测一下他的实现,这个和Model类的实现一样:安装这种写法,如果直接使用Python的类语法,生成的字段只能是类属性,这肯定是不能满足需求的。因此要使用一个字典来保存这些字段,然后覆盖魔法方法使得这个类用起来像一个字典。要更改类,就要使用到元类,这个元类把字段存储在一个字典中去,然后再把这些字段删除。因此构造方法使用的是一个列表。

    沈世军 10-21 02:30

    这里可以推测一下他的实现,这个和Model类的实现一样:按照Form字段定义时的这种写法,生成的字段只能是类属性,这肯定是不能满足需求的。因此要使用一个字典来保存这些字段,然后覆盖相应的魔法方法使得这个类用起来像一个字典。要更改类,就要使用到元类,这个元类把字段存储在一个字典中去,然后再把这些字段删除。因此构造方法使用的是一个字典。

    sanyang 01-01 12:55

    @ls 表示不太懂~~是不是有点像C#中的索引器~~

    qwe 01-20 06:33

    TypeError: unbound method as_p() must be called with ContactForm instance as first argument (got nothing instead)

    对这一段的评论会显示在这里
    >>> f = ContactForm({'subject': 'Hello', 'email': 'adrian@example.com', 'message': 'Nice site!'})
    对这一段的评论会显示在这里

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

    a<b>b</b> 12-22 06:55

    aa<b>b</b>

    a"><b>b</b> 12-22 06:56

    aa"><b>b</b>

    对这一段的评论会显示在这里
    >>> f.is_bound
    True
    对这一段的评论会显示在这里

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

    jawatang 07-24 07:20

    晕啊,一个是属性。一个是方法!

    ode2free 04-11 21:07

    是啊,好难记

    roger 11-22 14:15

    注意这个时候is_bound还是true

    对这一段的评论会显示在这里
    >>> 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
    []
    zhayefei 08-08 08:11

    f['message']._errors()

    lgy 11-13 07:57

    可能是版本的 原因,不加()也可以的

    sanyang 01-01 13:02

    为什么我这里无论怎么样都是[],没有错误信息~~

    Adoo 01-22 04:05

    NICE!

    对这一段的评论会显示在这里

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

    lei 03-22 11:06

    “邦定”应为“绑定”

    ode2free 04-11 21:21

    提供了一个字段与错误消息相映射的字典表,那么这样写也可以:f.errors['message']

    gdy 01-25 13:41

    @ode2free f.errors['message']与f['message'].errors到写法还是有区别的,如果message字段为通过验证到话,前者会出KeyError,后者返回[]。可以在这里敲f.errors['email']试试

    guest 02-22 04:44

    如果输入内容为多个空格,is_valid() 会判断为 True。

    qq_345421243 05-14 03:49

    f = ContactForm({'subject':'Hello','message':''}) print f.is_valid() 程序出错

    qq_345421243 05-14 06:09

    找到原因了,其实就是自己没有以这种方式打开cmd命令: python manage.py shell 当然还有一种解决办法是在代码之前加入下面这两句代码(配置环境用的): import os os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings") 上面两句代码拷贝自manage.py,他和python manage.py shell的作用是一样的,就是配置模块运行环境设置

    对这一段的评论会显示在这里
    >>> f = ContactForm({'subject': 'Hello', 'message': ''})
    >>> f.errors
    {'message': [u'This field is required.']}
    对这一段的评论会显示在这里

    最终,如果一个Form实体的数据是合法的,它就会有一个可用的cleaned_data属性。 这是一个包含干净的提交数据的字典。 Django的form框架不但校验数据,它还会把它们转换成相应的Python类型数据,这叫做清理数据。

    ode2free 04-11 21:24

    干净的--》整齐的

    xxsrobin 07-13 02:02

    找这个找了很久

    iewgnaw 08-22 08:30

    不管数据合不合法,调用is_valid()之后都有cleaned_data属性吧

    starof 02-10 03:09

    @iewgnaw ,如果数据不合法是没有cleaned_date属性的,我已经测试过会报错 AttributeError: 'ContactForm' object has no attribute 'cleaned_data'

    mr.liu 08-10 02:56

    回复楼上,数据不合法也有cleaned_data属性。f = ContactForm({'subject':'Hello','message':''}),f.cleaned_data 返回:{'email': u'', 'subject': u'Hello'}

    mr.liu 08-10 02:58

    再使用f.cleaned_data 前,用过 f.is_valid()方法检查,后面即使不合法,也会有cleaned_data属性

    对这一段的评论会显示在这里
    >>> 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}
    sephiroth 06-23 17:19

    这一段代码没有用引号标记字符串值

    ph4nut 07-25 06:25

    f = ContactForm({subject': Hello, email: adrian@example.com, message: Nice site!})里面的字典参数的键值少了引号!

    wyatt 12-28 12:01

    输入的内容,也是包含着引号的:{'email': u'adrian@example.com', 'message': u'Nice site!', 'subject': u'Hello'}

    kein 09-29 07:28

    同感

    Tianqi Tang 02-16 12:05

    为什么我这里f.cleaned_data会报错呢?说Contact_Form没有这个Attribute...

    Tianqi Tang 02-16 12:08

    奇怪,为什么只有先输入f.is_valid()再输入f.cleaned_data才会有返回?

    lincy 08-17 12:53

    根据原文,此处第一行代码确实少了引号

    coco 09-08 02:44

    @Tianqi Tang 我认为,cleaned_data 只是执行对数据的处理,没有对数据进行检验的功能,所以只有is_valid检验数据后,才能调用cleaned_data.

    stevenlee87 07-15 09:31

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

    mr.liu 08-10 03:02

    先is_valid方法校验数据,然后使用cleaned_data属性规范数据类型。

    对这一段的评论会显示在这里

    我们的contact form只涉及字符串类型,它们会被清理成Unicode对象。如果我们使用整数型或日期型,form框架会确保方法使用合适的Python整数型或datetime.date型对象。

    对这一段的评论会显示在这里

    在视图中使用Form对象

    对这一段的评论会显示在这里

    在学习了关于Form类的基本知识后,你会看到我们如何把它用到视图中,取代contact()代码中不整齐的部分。 一下示例说明了我们如何用forms框架重写contact()

    windy 01-22 08:01

    一下示例 应该是 以下示例

    sephiroth 06-23 17:20

    '一下示例' 改为 '以下示例'

    pengpeng 11-19 03:54

    为什么我这里执行的时候显示 Forbidden (403) 错误呢? 无论是提交空表但还是完整数据表单?

    li3p 01-07 07:45

    从settings.py中把下面的中间件注释起来就不会403了。 #'django.middleware.csrf.CsrfViewMiddleware',

    ok 05-10 08:16

    一下。改为以下.版主打拼音的?.

    陈超 06-02 02:25

    这里我是加了 from django.core.mail import send_mail 才成功的

    weetao 05-07 07:18

    @li3p:还是不要禁止csrf防御比较好吧

    啊董 12-19 05:57

    从settings.py中把下面的中间件注释起来就不会403了。 #'django.middleware.csrf.CsrfViewMiddleware', =================================== 注释掉果然可以了,但是又没有其他的办法呢

    小利子 01-11 11:43

    我按照https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ref-contrib-csrf上面的方法免除csrf,不行阿。

    logonovo 02-02 13:09

    类似这样 c = {} c.update(csrf(request)) # ... view code here return render_to_response('contact_form.html', {'form':form}, context_instance=RequestContext(request)) 对应模板加个token <form action="" method="post">{% csrf_token %}

    Aaron 09-24 09:07

    要完成contact功能除了在视图中中返回 RequestContext实例和在form中加入csrf标记外,还需在setting中正确配置email发送的相关参数。

    me1kd 11-14 17:41

    不建议注销掉CsrfViewMiddleware中间件, 将代码段 return render_to_response('contact_form.html', {'form': form}) 修改为: from django.shortcuts import render ... return render(request, 'contact_form.html', {'form': form}) 然后再在form中加入{% csrf_token %}即可。 相关链接:http://stackoverflow.com/questions/10388033/csrf-verification-failed-request-aborted

    对这一段的评论会显示在这里
    # 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>
    zhangliangfeng 07-27 02:49

    style="color:red","red"后面应该没有‘;’才对

    pengyao 11-02 08:35

    sendmail()缺少import

    Wally_Yu 02-15 06:55

    缺少 from django.core.mail import send_mail

    zxh 02-16 08:42

    模板中:{{ form.errors|pluralize }} 请问一下这句话是什么意思,特别是pluralize ,没看到python有这个函数呢?

    answer 03-06 02:35

    {{ form.errors|pluralize }}这个pluralize会先根据form.errors得到的结果来判断是否显示s,起到决定html中输出error还是errors。

    chain 03-06 06:59

    有人运行成功了吗?我这提示:'utf8' codec can't decode byte 0xa3 in position 36: invalid start byte 改了好久

    jenguo 03-18 19:12

    @chain 出现这个错误应该是你的网页编码问题,含有汉字。

    wulfric 05-01 16:21

    我想问一下,如果我在后台写的顺序是key1,key2,key3,那么前端怎么输出成key2,key1,key3?css可以吗?

    weetao 05-11 14:21

    为什么在SHELL中提示不存在cleaned_data这个属性?

    upupxjg 06-29 19:36

    这里在django1.4以上版本会报403错误,要在iews里改成render_to_response('contact_form.html',{'form':form},RequestContext(request)) 同时在表单里加{% csrf_token %}

    夸父 07-26 08:32

    https://docs.djangoproject.com/en/1.4/ref/contrib/csrf/#how-it-works http://blog.csdn.net/chenggong2dm/article/details/7729576 这两个网站都内解答如何配置post,不出现CSRF verification failed. Request aborted.的问题

    scarl 08-10 02:24

    @upupxjg 我1.4版本没有报错

    alex 10-26 07:29

    ContactForm这里是怎么来的??无法识别,运行的时候.

    Dboy 11-29 07:20

    form.errors|pluralize 这块,查文档如下: pluralize 使用形式:{{value | pluralize}},或者{{value | pluralize:"es"}},或者{{value | pluralize:"y,ies"}} 意义:如果value不是1,则返回一个复数后缀,缺省的后缀是's', 我在做的时候,把错误提示国际化改成了中文,那么问题就来了,中文跟英文是两种不同的表达方式,中文提示错误,后面根本没必要加"s",但是pluralize默认提供了这种方式,所以当用户没有填完整的表单时候,中文的错误提示后面无缘无故多了个“s”,这样的错误肯定不行。想了半天,使用 {{form.errors|pluralize:""}}解决了问题,希望其他人遇到此类问题,这个评注可以有点帮助。

    clearshadow 01-08 07:35

    else: form = ContactForm() return render_to_response('contact_form.html', {'form': form}) 请问这段代码中,ContactForm()没有填写参数,form中的值是什么?还能是request里带来的有错误的值么?

    排骨饭 01-24 05:10

    发现一个问题,正确实例化f后,必须先执行下 is_valid()方法,然后f.cleaned_data才会有数据

    Tianqi Tang 02-16 15:02

    @upupxjg 需要在views里加入from django.template import RequestContext

    athos 03-13 15:52

    Forbidden (403) CSRF verification failed. Request aborted.这个错误有点坑,多谢楼上各位的讨论

    xpy 04-07 07:10

    求问,为什么不是cd[]而是cd.get[]?

    sdf 05-08 15:03

    django.middleware.csrf.CsrfViewMiddleware开启了 用RequestContext代替了Context 在form里加了{% csrf_token %} 还是显示403 CSRF verification failed. Request aborted.错误 django版本1.5.1

    fenixma 05-10 02:00

    这个问题尝试了楼上的各种方法不能解决,最后把模板名字改掉就可以了...不知道是不是1.5版本模板解析的bug

    fenixma 05-10 02:03

    原因原来是在搜索路径下有模板重名了...囧...

    张晓 05-27 03:40

    要想显示,需要设置url

    winkdiney 05-30 14:01

    如果表出错,django会返回错误信息,自动插入到forms里面,例子如下 <tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" name="subject" type="text" value="a" /></td></tr> <tr><th><label for="id_email">Email:</label></th><td><ul class="errorlist"><li>Enter a valid email address.</li></ul><input id="id_email" name="email" type="text" value="jlkajdlfj" /></td></tr> <tr><th><label for="id_message">Message:</label></th><td><input id="id_message" name="message" type="text" value="hehe" /></td></tr>

    Kevin 06-25 08:19

    [Errno 111] Connection refused 有人遇到吗?猜测是没有真实的发件环境导致的。

    Kevin 06-25 08:20

    [Errno 111] Connection refused 有人遇到吗?猜测是没有真实的发件环境导致的。 —— 自己回答自己。“(根据服务器的设置,当send_mail()被调用时,你将得到一个错误提示。而这是另一个问题。)”好吧,文章里面提到了- -!但是没有解决方法。

    Chris 06-27 16:54

    這邊的send_mail欄位是不是怪怪的,官方文件是說接收者列表要放在第四個,所以cd.get('email','..')應該是放在第四欄的列表中吧

    Chris 06-27 16:54

    噢我誤會他的意思了..抱歉

    Chris 06-27 17:27

    那這樣寄件人欄位的用意是甚麼= =?? siteowner收到信的時候,顯示的還是自己站的email_address阿

    gegev 07-04 00:57

    views.py中最后一行代码:“return render_to_response('contact_form.html', {'form': form})”,其中form并未在前面声明、定义,为啥这里运行不会出错呢?

    Roy 07-12 03:07

    1.4以上版本的csrf权限问题解决办法: http://blog.csdn.net/chenggong2dm/article/details/7729576 1.5版本亲测有用

    匿名读者 08-18 08:37

    这里为什么要用clean方法,直接用request_POST不也是返回一个字典吗

    jim 09-10 10:48

    当提交空的内容,2个地方都提示 This field is required.,这2句内容是哪行代码产生的?谢谢!

    ea 10-15 07:07

    cd.get('email', 'noreply@example.com'), ['siteowner@example.com'],

    苏国峰 10-21 15:16

    @jim 是表单类自带的功能

    lgy 11-13 08:47

    [error 111]connection refused 这怎么解决??

    skyler 01-02 13:27

    跳转的时候运行超时 我真的无语了

    dmhz 01-22 10:02

    解决csrf,最简单的办法就是把 MIDDLEWARE_CLASSES 中的'django.middleware.csrf.CsrfViewMiddleware',禁用掉

    wh 07-08 08:38

    为什么我点了按钮表被清空 不显示错误 直接刷新页面了

    mihello 08-12 09:38

    大家没有出现不填email的报错,cd.get('email', xxx@xxx.com') 'email' in cd 是True的那怕是表单为空,cd['email'] == '' 。所以get这个方法有问题,get本身是key不存在的时候才起作用的。疑惑中

    journeyto 08-21 05:15

    之前的errors呢?不需要了吗?

    journeyto 08-21 05:19

    'ContactForm' object has no attribute 'update' 我遇到这个错误~

    Radon 09-22 11:49

    cd.get 不懂,求解释

    潇洒走一回 12-26 08:20

    # views.py: from django.shortcuts import render_to_response from books.forms import ContactForm from django.template import RequestContext 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', '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},RequestContext(request)) # urls.py: from django.conf.urls import patterns, include, url from django.contrib import admin admin.autodiscover() from books import views urlpatterns = patterns('', # Examples: # url(r'^$', 'mysite.views.home', name='home'), # url(r'^blog/', include('blog.urls')), url(r'^admin/', include(admin.site.urls)), (r'^contact_form/$',views.contact), ) # forms.py: 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 # 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="/contact_form/" method="post"> {% csrf_token %} <table> {{ form.as_table }} </table> <input type="subm

    Adoo 01-22 05:09

    这段代码跟英文版的出入很大,建议看英文版

    唐琅 03-26 05:23

    cd.get('email', 'noreply@example.com') 这句即使获得空值,也会返回空值而不是后面的'noreply@example.com',这个怎么办?

    一贴灵 04-16 03:04

    send_mail(主题,内容,发件人,收件人) 但在示例中,cd.get('email','...')应该是取了收件人的地址,真正的收件人只能写在程序中,对新手易引起误解;不知我指出的对不对 send_mail(cd['subject'],cd['message'],'send@hot.com',cd['email'],'rec@hot.com'],

    西木柚子 08-15 01:15

    哈哈,看来不少人在这里出了问题,我也是折腾了半天,终于找到解决办法了。 具体看这个帖子,博主分析的很详细,并且给出了多中解决办法 http://www.qttc.net/201209211.html

    草履虫KB 06-05 14:41

    这边HttpResponseRedirect中的/contact/thanks/ 在url中没有定义,在submit后就无法跳转了吧?

    jett 07-27 06:37

    Good

    匿名读者 12-08 08:44

    这个教程讲得好细!

    horizonshd 09-15 11:19

    forms.py文件中ContactForm类中定义的 email = forms.EmailField(required=False) 会在没有输入右键地址时,会将 ''赋值给email,一起传递到view.py下的contact(),执行到cd.get('email', 'noreply@example.com')这一句时不会像预想的那样将 noreply@example.com 赋值给 email. 此处的处理需要更换一下,然而我也不知道好的处理方式。

    horizonshd 09-15 11:20

    forms.py文件中ContactForm类中定义的 email = forms.EmailField(required=False) 会在没有输入邮件地址时,会将 ' '赋值给email,一起传递到view.py下的contact(),执行到cd.get('email', 'noreply@example.com')这一句时不会像预想的那样将 noreply@example.com 赋值给 email. 此处的处理需要更换一下,然而我也不知道好的处理方式。

    匿名读者 01-14 11:02

    from django.core.mail import send_mail # send_mail的参数分别是 邮件标题,邮件内容,发件箱(settings.py中设置过的那个),收件箱列表(可以发送给多个人),失败静默(若发送失败,报错提示我们) send_mail( 'Subject here', 'Here is the message.', 'from@example.com', ['to@example.com'], fail_silently=False )

    匿名读者 07-27 06:38

    楼上的方法都过时了,没用,我用的是 Django1.11,解决csrf的方法 在views.py文件头部加入 from django.views.decorators.csrf import csrf_exempt 在def contact(request)的上一行插入 @csrf_exempt

    pixiu 04-03 21:07

    Django3.x render_to_response已弃用,使用render方法+html插入{% csrf_token %}之后不起效 后续在函数开头加了@csrf_protect,生效,删除后失效 后面不知道我干了什么总之它突然就不加也生效了orz

    对这一段的评论会显示在这里

    看看,我们能移除这么多不整齐的代码! Django的forms框架处理HTML显示、数据校验、数据清理和表单错误重现。

    对这一段的评论会显示在这里

    尝试在本地运行。 装载表单,先留空所有字段提交空表单;继而填写一个错误的邮箱地址再尝试提交表单;最后再用正确数据提交表单。 (根据服务器的设置,当send_mail()被调用时,你将得到一个错误提示。而这是另一个问题。)

    Adoo 01-22 05:38

    原来作者都说是发送不了的。。。

    baichenjia 04-20 02:24

    可以发送,我已经成功发送了 setting.py中添加: EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = 'smtp.163.com' EMAIL_PORT = 25 EMAIL_HOST_USER = '自己的邮箱地址 ' EMAIL_HOST_PASSWORD = ' 自己邮箱的密码'

    hy 05-25 03:34

    嘿嘿,记录下!邮件发送成功,用的smtp.qq.com,收是163邮箱

    wayne 08-18 03:08

    Forbidden (403) CSRF verification failed. Request aborted. 出现了这样的问题

    friday 09-14 13:20

    @wayne To fix this issue, add: from django.template import RequestContext to the views.py file and this added argument for the render_to_response function: context_instance = RequestContext(request) Be sure to add {% csrf_token %} within the <form> tags in the template

    徐云东 11-28 15:06

    https://django-chinese-docs-14.readthedocs.org/en/latest/topics/email.html#id10 可以通过控制台查看测试邮件内容!

    istyle 12-29 08:21

    @Adoo 在DEFAULT_FROM_EMAIL设置 并且邮件字段为空时 可以发送邮件 否则报501错误 什么不一致的问题

    cjf 03-28 08:34

    发送成功!mark一下 EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_USE_TLS = False EMAIL_HOST = 'smtp.163.com' EMAIL_PORT = 25 EMAIL_HOST_USER = 'm13533247097@163.com' EMAIL_HOST_PASSWORD = '****' DEFAULT_FROM_EMAIL = 'm13533247097@163.com'

    对这一段的评论会显示在这里

    改变字段显示

    对这一段的评论会显示在这里

    你可能首先注意到:当你在本地显示这个表单的时,message字段被显示成input type=”text” ,而它应该被显示成<textarea >。我们可以通过设置 widget 来修改它:

    hekun 07-31 03:01

    为什么我加不加widget=forms.Textarea 感觉都完全一样? 到底会有什么区别?

    slothsimon 07-31 08:10

    @hekun 单行文本和多行文本,后者可以有滚动条

    对这一段的评论会显示在这里
    from django import forms
    
    class ContactForm(forms.Form):
        subject = forms.CharField()
        email = forms.EmailField(required=False)
        message = forms.CharField(**widget=forms.Textarea** )
    wyatt 12-28 13:07

    我修改了表单显示为textarea,但在浏览器中去看不到改变呢,还是老样子?

    soul_eater 09-02 09:57

    我遇到了一个非常大的问题,我按照前面的做法改了contact_form.html,但是,表单没有变化,最后个message的表单还是“Textarea”的,后来我把这个html文件重命名了一下变成test.html,就正常了,不知道为什么会这样,我缓存都清过了。

    soul_eater 09-02 10:01

    我错了- -,还有一个文件没有删掉...他先加载了那个文件了

    Killpanda 11-22 16:19

    message部分是否可以使用 message = forms.TextFiled() ?

    jett 07-27 06:50

    forms.Textarea where to see it.

    对这一段的评论会显示在这里

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

    对这一段的评论会显示在这里

    考虑一下Field类表现 校验逻辑 ,而部件表现 显示逻辑

    对这一段的评论会显示在这里

    设置最大长度

    对这一段的评论会显示在这里

    一个最经常使用的校验要求是检查字段长度。 另外,我们应该改进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)
    zlleah 01-07 05:33

    限制长度之后,只能输入到最长(或最短),好强大的说

    zlleah 01-07 06:00

    另外,是以字符为单位检查的,注意区分下面自定义的方法判断

    hekun 07-31 04:33

    @zlleah 如果max_length=10 是指在浏览器中输入的字母不能超过10个吗?也即超过10个字母就不能再输入了。可是我可以一直输入啊,真郁闷。

    xoozi 08-02 07:59

    浏览器版本问题,用chrome,maxlength有效

    atlas 10-02 17:44

    我使用chrome也有效

    mr.liu 08-10 07:38

    高!

    猪头哥哥 12-11 08:00

    max_length是限制最多输入字符

    06-15 03:43

    对这一段的评论会显示在这里

    选项min_length参数同样可用。

    对这一段的评论会显示在这里

    设置初始值

    对这一段的评论会显示在这里

    让我们再改进一下这个表单:为字subject段添加 初始值"I love your site!" (一点建议,但没坏处。)为此,我们可以在创建Form实体时,使用initial参数:

    binsen 02-06 15:51

    “为字subject段”→“为subject字段”

    电饭锅 02-11 08:35

    好可爱的作者

    对这一段的评论会显示在这里
    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})
    jwfy 09-21 13:16

    加上这个初始化为什么我这完全没有变化

    苏国峰 10-22 14:00

    直接url上回车。

    baichenjia 04-20 02:49

    如何可以写中文?

    mr.liu 08-10 07:43

    在配置文件上面写:#coding:utf8

    stephen 02-11 03:08

    加了这个初始化后,{{ form.as_table }}这一句报错了

    jiangm_ 07-05 07:26

    [`'siteowner@example.com`_']没看懂,谁给说说

    电饭锅 02-11 08:36

    楼上,这就是个举例子用的邮箱地址,完全可以换成别的

    对这一段的评论会显示在这里

    现在,subject字段将被那个句子填充。

    ph4nut 07-25 06:36

    ”如果仅传入* 初始值* 数据,表单是unbound的,那意味着它没有错误消息。“ 这个值得注意,因为表单第一次显示的时候,是不需要显示错误讯息的。

    liximomo 11-12 12:50

    如果为'subject'赋了默认值,那么以默认值提交表单,默认值会被最为参数传递给post或get么,request.POST.get(subject)是空还是默认值?

    Chris 06-28 07:13

    ls,是默認值

    mr.liu 08-10 07:57

    初始值没有默认错误信息,errors属性是空字典,很关键。

    leo 11-16 03:48

    这个功能很鸡肋啊,直接在HTML中设置默认值不好吗

    对这一段的评论会显示在这里

    请注意,传入 初始值 数据和传入数据以 绑定 表单是有区别的。 最大的区别是,如果仅传入 初始值 数据,表单是unbound的,那意味着它没有错误消息。

    jett 07-27 07:12

    oh no

    对这一段的评论会显示在这里

    自定义校验规则

    ɾ��ȸ� 10-20 23:20

    ɾ��ȸ��������Ϣqq364961738 �������,�ٶ����Ϣɾ��961738 ����Σ������޹�˾רҵ����Ϣ��� ,������Ϣ������� �ٶȿ� ������������ٶȸ��������������������ɾ���Ϣɾ��ɾ��ɾ��ɾ��ɾ��4351999���683238007 www.weijigongguan.cn www.315network.com ɾ��ȸ��������Ϣqq364961738

    咦,楼上为什么乱码? 07-28 01:12

    cstriker1407 08-15 06:04

    广告。给屏蔽了

    大力出奇迹 04-09 17:28

    这个拜托在英文原文是不是come on。。。。。

    匿名读者 06-30 09:49

    four words or more, please.

    shabio 10-13 06:46

    还会撒娇?

    藍藍 02-15 02:15

    很棒的作者!

    对这一段的评论会显示在这里

    假设我们已经发布了反馈页面了,email已经开始源源不断地涌入了。 这里有一个问题: 一些提交的消息只有一两个字,我们无法得知详细的信息。 所以我们决定增加一条新的校验: 来点专业精神,最起码写四个字,拜托。

    对这一段的评论会显示在这里

    我们有很多的方法把我们的自定义校验挂在Django的form上。 如果我们的规则会被一次又一次的使用,我们可以创建一个自定义的字段类型。 大多数的自定义校验都是一次性的,可以直接绑定到form类.

    对这一段的评论会显示在这里

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

    Keen 07-06 07:17

    num_words = len(message.split()) 这代码有误,改成 num_words = len(message) 即可。

    zackmore 11-07 07:59

    @Keen 你理解错误吧?len(message.split())是计算message中总共有多少单词,而len(message)是计算message中有多少个字符了。中英文环境还是有区别的

    li 12-05 03:05

    错误:num_words = len(message.split()) 正确:num_words = len(message.strip())

    mr.liu 08-10 08:16

    我是这么理解的,split没有参数,就会以空格或者回车符作为分割符,将字符串拆分为列表返回。文中所说num_words < 4 ,也就是你得写4个字符,3个空格或者3个回车间隔,才能满足条件。

    对这一段的评论会显示在这里
    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
    宾临城下 05-03 13:25

    num_words = len(message.join(message.split()))

    wyatt 12-28 13:38

    校上正解,不这么修改,我在提交中文的时候,出现问题。

    wyatt 12-28 13:38

    楼上正解,不这么修改,我在提交中文的时候,出现问题。

    ode2free 04-12 09:45

    @宾临城下 文中原意是指最少包含4个单词,比如 how are you today,但是不适用没有分隔的中文。你这样改不如直接写成 len(message)

    蛟龙 08-28 05:32

    这段是为了演示clean_xx方法 如果只是规定最小长度的话,上面说的min_length就很方便

    lianjie.ning 10-12 03:28

    >>> m = '111111111' >>> len(m.split()) 1 >>> m = '1 1 1 1 1 1 1 1 1' >>> len(m.split()) 9

    xepher 12-20 07:58

    一楼num_words = len(message.join(message.split())) 这么写确实不如直接写len(message)了,同意4楼的

    Wally_Yu 02-15 07:54

    同意,改为如下,原文意义通过: num_words = len(message)

    newuil 06-07 06:35

    num_words = len(message.split()) if num_words < 4: #代码想要表示的是message的长度不少于4行,而不是4个字母

    匿名读者 11-13 10:51

    mark ..split用法

    benxiang 12-21 08:18

    我认为一楼不妥,这样的话就不是四个单词而是四个字母了。。 求楼下大神给一个分辨中文的方法吧。。。

    dingyj 02-25 08:56

    错误信息为什么都显示在栏位上方,而不是栏位的下方,或者后面

    justin.huang 10-21 04:52

    message.split()是把提交的textArea 按照行分组了 所以len(message.split())的意义是看message提交了几行。

    xu 10-26 12:15

    split()不是去掉字符串前的 转行符号吗? len不是求字符串长度吗?

    Belter xin 08-31 08:43

    django 1.10, 没效果

    yiguxianyun 09-09 06:43

    “Python split()通过指定分隔符(默认为空格)对字符串进行切片,返回分割后的字符串“列表””,len()表示列表有多少个元素!

    rain 03-22 09:00

    django1.0版本, 在forms.py里定义一个自定义校验函数, 在类ContactForm里, message字段添加属性validators=[自定义校验函数名]。 # 自定义自动校验规则 def validate_message(message): num_words = len(message.split()) if num_words < 4: raise forms.ValidationError("Not enough words!") return message --------------------------分割线------------------ class ContactForm(forms.Form): message = forms.CharField(widget=forms.Textarea, validators=[validate_message]) 经测试,可以达到自定义校验的效果。

    rain 03-22 09:01

    django1.10版本, 在forms.py里定义一个自定义校验函数, 在类ContactForm里, message字段添加属性validators=[自定义校验函数名]。 # 自定义自动校验规则 def validate_message(message): num_words = len(message.split()) if num_words < 4: raise forms.ValidationError("Not enough words!") return message --------------------------分割线------------------ class ContactForm(forms.Form): message = forms.CharField(widget=forms.Textarea, validators=[validate_message]) 经测试,可以达到自定义校验的效果。

    Lily Paper 11-03 03:05

    message.split()返回的是段落列表,比如abc\ncda\nuiwd\nddd\n,总共有4个"\n",表示有四个段落,那么返回的len(message.split())就是列表展开为4的长度,而len(message)返回的就只是字符个数

    Lily Paper 11-03 03:10

    .split()用的就是通过分隔符如:空格、换行(\n)等,方式进行的切片

    对这一段的评论会显示在这里

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

    xxsrobin 07-13 02:03

    上面的方法很有用,自定义验证规则。good

    xxsrobin 07-13 02:04

    注意,自定义的验证需要clean_开头

    ericyou 06-25 07:50

    clean开头的规则有点诡异。。。

    wdmyong 06-29 11:33

    额,我还是要在调用cleaned_data之前先调用is_valid(),否则报调用cleaned_data错误。

    xoozi 08-02 08:09

    Django框架把clean的动作绑定到校验中是很自然的,clean前肯定需要确保表单通过校验,而且cleaned_data是一个属性,不是方法这样可以执行的东西,自然需要在某个地方来执行clean的动作。

    LeBron 05-13 07:11

    这个特性真的是高度集成的框架才会做到这步

    对这一段的评论会显示在这里

    特别地,clean_message()方法将在指定字段的默认校验逻辑执行 之后 被调用。(本例中,在必填CharField这个校验逻辑之后。)因为字段数据已经被部分处理,所以它被从self.cleaned_data中提取出来了。同样,我们不必担心数据是否为空,因为它已经被校验过了。

    ��� 11-25 18:54

    ����һ�ҷ��Ϣ�, ���һ�ҷ��Ϣ�, �ں���ҷ��Ϣ�, ĵ����һ�ҷ��Ϣ�, �̨����ҷ��Ϣ�, ���˹һ�ҷ��Ϣ�, ���һ�ҷ��Ϣ�, ����ҷ��Ϣ�, ˫Ѽɽһ�ҷ��Ϣ�, �׸���ҷ��Ϣ�, ���һ�ҷ��Ϣ�, ���������Ϣ�, ����Ϣ�� ���Ϣ�� ���Ϣ�� ����Ϣ�� ����Ϣ�� ���Ϣ�� μ��Ϣ�� ͭ���Ϣ�� ���Ϣ�� ʮ��Ϣ�� �������Ϣ, ������Ϣ, �������Ϣ, �����Ϣ, �Ŀ������������������ת����ְ���Ƹ�������ѵ���ҽ̡��������������ά���װ������������ҽ�����顢�����������������������ҵ����ȡ� һ�ҷ��Ϣ� ��ѷ��Ϣ��ѹ� www.1jfl.com www.1jfl.cn www.1jfl.com.cn 5016

    苏国峰 10-22 16:02

    当执行is_valid()的时候,会对每个field进行检查,并立即产生cleaned的数据。如果有clean_开头的函数,则开始执行此函数(此时cleaned的数据已经可以用了)。

    徐云东 11-28 23:45

    请问楼上的是在哪里看到的这个信息的?

    对这一段的评论会显示在这里

    我们简单地使用了len()和split()的组合来计算单词的数量。 如果用户输入字数不足,我们抛出一个forms.ValidationError型异常。这个异常的描述会被作为错误列表中的一项显示给用户。

    jason 03-01 12:49

    文中说会将此异常作为错误列表中的一项,那我输入3个字符,它怎么还是跳转的填写表格的网页,并没有在这个网页中提示错误原因。求指导!!

    monster 04-01 02:43

    表示的是单词数 不是字母数

    noooop 04-19 14:06

    千万不要用作中文字数统计,会悲剧的。用len()可以实现

    hy 05-25 07:30

    按照空格来判断字(词)数是不是小于4个,小于则抛错啊,中文英文都没问题

    sos 12-22 02:46

    谁写中文的时候 每个字后边还加空格啊 英文单词间是必须有空格的

    对这一段的评论会显示在这里

    在函数的末尾显式地返回字段的值非常重要。 我们可以在我们自定义的校验方法中修改它的值(或者把它转换成另一种Python类型)。 如果我们忘记了这一步,None值就会返回,原始的数据就丢失掉了。

    athos 03-13 16:36

    这句话的意思是 把 return message 去掉的话,会把message值清空吗?但是我测试结果似乎没变化,郁闷

    qq_345421243 05-14 07:08

    页面成功后转向的那个页面request.post已经取不到message这个值了

    qq_345421243 05-14 08:11

    晕,越来越晕了,谁解释一下,我也糊涂了

    qq_345421243 05-14 08:19

    终于搞明白了,如果去掉return message,那么form.cleaned_data['message] 这个值就为空,但是request.POST.get('message','')这个值还是有的,就是你提交的表单的那个值

    Chris 06-28 08:41

    總之就是你自定驗證完沒有return,message值就會為空,到時候信件就沒有message

    streethacker 07-27 09:41

    这个地方实有点迷惑,我个人是这么理解的(写的有点乱,大家多给意见): 当执行form=ContactForm(dict/request.POST)创建了一个form对象时,form中便包含了三个属性subject/email/message, 它们分别接收来自ContactForm的字典参数(例如:{'subject':'hello', 'email‘:'reply@example.com','message':'Nice Site'}) 来实现赋值。但是这三个参数要通过验证后才会被写form.cleaned_data字典中。 以message属性为例,首先执行默认的校验(the default validation logic for a given field),若校验通过,则进而执行我们自定义的clean_message校验,若clean_message校验也通过,则return一个校验结果,这个校验结果被返回给message属性。若三个属性的校验都通过,则这三个属性的值就被写入cleaned_data字典。如果我们遗漏了return语句,django默认返回None,由于校验并不受return语句的影响,None依然被返回给message,且三个属性结果被写入cleaned_data中,于是cleaned_data的内容便为:{'subject':'hello','email':'reply@example.com','message':None}。 由之前的例子我们可以看到: cd = form.cleaned_data send_mail(cd['subject'],cd['message'],cd.get('email','noreplay@example.com),['siteowner@example.com']) 这样一来,cd['message']原本要获得的内容'Nice Site',因为我们遗漏return语句,变成了None,且作为邮件的内容被发送了出去。

    Aaron 09-24 13:36

    我觉得主要是如果你不返回message的话,django默认会返回None给message,然后再存入cleaned_data中。所以收到的email中内容应该是空的。

    asuka 06-23 03:10

    纠正楼上一点,clean_message里的message就是从cleaned_data里提取出来的

    starof 02-10 05:54

    如果去掉return message,那么form.cleaned_data['message] 这个值就为空,但是request.POST.get('message','')这个值还是有的,就是你提交的表单的那个值。但是使用Form框架就是要用它的cleaned_data的值,所以千万写上return message。

    Belter xin 08-31 08:25

    python中的函数,默认return None

    猪头哥哥 12-11 08:10

    有个return是很好的习惯

    对这一段的评论会显示在这里

    指定标签

    对这一段的评论会显示在这里

    HTML表单中自动生成的标签默认是按照规则生成的:用空格代替下划线,首字母大写。如email的标签是"Email" 。(好像在哪听到过? 是的,同样的逻辑被用于模块(model)中字段的verbose_name值。 我们在第五章谈到过。)

    wzdxt 07-16 07:21

    from contact.forms import ContactForm 应为 from mysite.forms import ContactForm

    wzdxt 07-16 07:24

    model应为模型 翻译成模块会造成误解

    RobinChan 02-07 23:40

    从这里开始到本章结束看得很莫名其妙,还是转去看英文版吧。

    cgirl 07-03 09:50

    版本:Django version 1.4.20 首字母不会自动转为大写

    对这一段的评论会显示在这里

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

    Black Glory 06-23 10:15

    模块=>模型

    hekun 07-31 03:44

    加上label='Your e-mail address'后,在浏览器中没有看到什么变化。

    Aaron 09-24 13:43

    @hekun 我的是变化为新的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)
    Lang 09-08 09:31

    这里新加的标签中的文字就是你要它显示的样子,为了统一,要手动大写Y了。

    Taburiss 05-05 05:46

    这个label好像不能用

    zlleah 01-07 06:11

    @Taburiss,可以

    jwfy 09-21 13:47

    我这除了该成中文会出现乱码的问题, 其他的随便什么字符都是可以的 这个中文乱码怎么解决呢?我在那个contact_from.html 里面写了格式是UTF-8的,可还是乱码。。。。

    kr 10-12 08:41

    @jwfy 要显示中文 共需两步 在你有中文的脚本的文件头添加 # -*- coding: utf-8 -*- 之后把这个脚本转成utf8格式

    huangtc 12-10 03:19

    貌似label的位置要靠后,否则不会生效

    luoyingtian 01-23 07:38

    更新label需要重启服务器

    misutt 10-20 10:02

    @luoyingtian 不用重启 刷新下就好了

    TTTsand 10-22 09:11

    @misutt 你好,为什么我填写邮箱就会报553,不写邮箱就没有问题,一直搞不懂是怎么回事。本章上面的例子也是这个问题....

    Shawn-Huang 11-19 17:05

    @TTTsand 邮箱格式必须跟siteowner@example.com一样,比如'xxxxxx@163.com', 具体情况参考http://blog.csdn.net/pegasuswang_/article/details/43154535, 慢慢琢磨ba

    对这一段的评论会显示在这里

    定制Form设计

    对这一段的评论会显示在这里

    在上面的contact_form.html 模板中我们使用{{form.as_table}} 显示表单,不过我们可以使用其他更精确控制表单显示的方法。

    对这一段的评论会显示在这里

    修改form的显示的最快捷的方式是使用CSS。 尤其是错误列表,可以增强视觉效果。自动生成的错误列表精确的使用<ul class=”errorlist”>,这样,我们就可以针对它们使用CSS。 下面的CSS让错误更加醒目了:

    fly2fire 02-27 03:05

    print f.['message'].errors 可以得到 <ul class="errorlist"><li>This field is required.</li></ul>

    对这一段的评论会显示在这里
    <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>
    athos 03-13 16:52

    谁能说下这一段应该如何使用在例子中?

    kalduin 04-19 07:15

    回楼上,添加到那个./templates/c**_f**.html的任意标签之间比如:复制到</head>和<body>之间

    lincy 08-18 01:19

    一般是在html的title下面,head里面

    coco 09-08 07:34

    我想在contact文件夹里建立一个css文件,然后在这里引用,可是怎么都不对,没有特效,求指教

    cala 04-19 14:54

    将这段放在<title>Contact us</title>后面,ul.errorlist中errorlist为灰色什么情况,菜鸟不懂。

    maxiaolei 06-19 08:14

    CSS怎么分离出来一个文件夹?

    Belter xin 08-31 09:32

    在html<head>标签内添加下面这句话,引用单独的css文件 <link rel="stylesheet" href="css/style.css" />

    猪头哥哥 12-11 08:25

    这里的做法 在template文件夹内建立一个css文件夹 新建Stylesheet文件 把css代码拷进去,然后再base.html中加入css引用。之后所有你extends base的页面都可以用到其中的样式,当然这需要你自己添加在页面中<ul class=”errorlist”>CSS的用法也是有很大学问的 值得学习

    猪头哥哥 12-11 08:37

    不好意思 纠正一下 这里涉及到静态文件的引入我没有意识到 附上网址http://blog.csdn.net/liqiancao/article/details/66151287

    对这一段的评论会显示在这里

    虽然,自动生成HTML是很方便的,但是在某些时候,你会想覆盖默认的显示。 {{form.as_table}}和其它的方法在开发的时候是一个快捷的方式,form的显示方式也可以在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>
    宾临城下 05-03 13:24

    num_words = len(message.join(message.split()))

    Black Glory 06-23 10:20

    len(message)

    zbyzhlsp 12-09 16:20

    何必呢,我不想用form类在前台显示。

    naturalaw 06-07 06:30

    div class="field" 需要自己定义

    匿名读者 08-13 08:41

    form.errors 前台展示容易被恶意串改页面

    lincy 08-18 01:45

    更难看了。。。

    jwfy 05-04 03:56

    还是自己写吧。。。可是好像还是得靠他自己生成了。。。

    windy 07-28 08:30

    forms框架貌似很牛.. 可是这样对form重写好麻烦....

    Adoo 01-22 06:16

    也没好看多少

    hy 05-25 08:00

    好丑!

    匿名读者 07-02 11:01

    好是好,自动生成html,可是如果我要使用第三方框架例如bootstrap美化生成的组件该怎么做呀?

    te 10-05 14:34

    如果我想给input标签添加样式怎么做啊

    Lionel.Shen 10-14 09:50

    使用form框架,难道html也由开发来写了?还不如传统的html+css+jq模式,还可以使用bootstrap美化。

    匿名读者 02-23 06:38

    想要自定义form样式的,可以来参考这篇博文:http://mageelen.github.io/2016/04/12/Skills/form-style-in-django/

    匿名读者 07-09 09:45

    自定义表单样式这块儿感觉还是自己写吧,django自身的这个表单

    对这一段的评论会显示在这里

    {{ 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>
    qq_345421243 05-14 09:23

    这章讲得不是很好

    naturalaw 06-07 06:41

    这不是有序列表,是无序列表 ol order list. ul un....

    匿名读者 08-18 08:57

    感觉最后两段代码莫名其妙,不知道干嘛使得

    huaye 08-02 16:10

    这章讲的完全不像是同一个人翻译出来的,

    starof 02-10 08:50

    最后两段是翻译的有点难懂,可参考 http://www.cnblogs.com/starof/p/4271810.html

    www 02-23 17:10

    个人觉得这段的意思就是,在不用forms模块前,可以对表单进行渲染;在用了forms模块之后,依然是非常flexible的,仍然可以对错误和fields进行css渲染,nothing more。

    mr.liu 08-10 10:06

    这什么作用....???楼下接着回答下

    mr.liu 08-11 03:57

    第一个判断。如果 form.message.erros 为真,就在div中添加errors样式。然后第二次判断,为真就循环显示错误信息。

    对这一段的评论会显示在这里

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

    coolspeed 11-10 20:41

    有序列表->无序列表

    andmz 03-08 07:16

    ...in an unordered list

    lincy 08-18 02:06

    这样会出现两个重复的错误啊,求解

    starof 02-10 08:49

    @lincy 去掉一种就好了,这里只是说可以这么用,不一定要这么用,可参考 http://www.cnblogs.com/starof/p/4271810.html

    对这一段的评论会显示在这里

    下一章

    对这一段的评论会显示在这里

    这一章总结了本书的介绍材料,即所谓“核心教程”。 后面部分,从第八章到第十二章,将详细讲述高级(进阶)使用,包括如何配置一个Django应用程序(第十二章)。

    对这一段的评论会显示在这里

    在学习本书的前面七章后,我们终于对于使用Django构建自己的网站已经知道的够多了, 本书中剩余的材料将在你需要的时候帮助你补遗。

    jack 07-05 12:05

    妹的,这章看的最乱,代码各种错!

    各种没头绪 07-28 01:29

    终于把这一章看完了 07-28 01:45

    xavier 07-29 08:31

    看完七章后,我写的一个非常简单的留言板应用:D https://github.com/dd1994/message_box

    misutt 10-20 10:08

    终于看完这一章!!各种改各种错各种百度各种砸鼠标!但是感觉还是糊糊的(╯‵□′)╯︵┻━┻

    匿名读者 01-06 09:11

    这章前后逻辑混乱 css文件放哪,标签中用哪 都没有 看完后晕乎乎的

    CC 07-07 05:00

    原来大家都看的晕乎乎的,me too!我还以为深入后难起来了呢

    Shawn-Huang 11-19 17:26

    这一章用了至少三天才在运行时候没问题,表示心好累...

    blackysy 07-04 07:54

    看的晕的可以参考参考这个哦,本人总结写的一些,有疑问可以留言给我。 https://www.cnblogs.com/blackysy/p/11126827.html

    对这一段的评论会显示在这里

    第八章我们将回头、并深入地讲解 视图和URLconfs(第三章已简单介绍)。

    对这一段的评论会显示在这里

    Hosting graciously provided by

    徐云东 11-29 00:24

    提供主机人名呢?by who 啊?

    对这一段的评论会显示在这里
    © 树叶书屋 · 学习 / 旅行 / 资源 每一段都可以评论交流,欢迎留下你的想法。