调试笔记
1. submit和button的区别
input type="submit" 和"button"有什么区别? - 知乎
在一个页面上画一个按钮,有四种办法:
<input type="button" />
这就是一个按钮。如果你不写javascript 的话,按下去什么也不会发生。
<input type="submit" />
这样的按钮用户点击之后会自动提交 form,除非你写了javascript 阻止它。
<button>
这个按钮放在 form 中也会点击自动提交,比前两个的优点是按钮的内容不光可以有文字,还可以有图片等多媒体内容。(当然,前两个用图片背景也可以做到)。它的缺点是不同的浏览器得到的 value 值不同;可能还有其他的浏览器兼容问题(葛亮)。其他标签,例如 a, img, span, div,然后用图片把它伪装成一个按钮。
用法:
表单数据这个特性,是无法混淆的。
<button>
无法把自己当成Form的数据。
所以,如果只是个单纯的按钮,触发一些画面动作,请使用<button>
;
反之,会把画面的数据提交给Server的,一般用<input type="submit" />
,当然<button>
+JS也完全可以取代。
html中submit和button的区别(总结)劤步新浪博客
写区别时和其他说法差不多:
INPUT type=submit 即发送表单,按回车提交表单
INPUT type=button 就是单纯的按钮功能,提交的是innerTEXTsubmit:特殊的button,会自动将表单的数据提交,onClick方法不加return 会自动提交,并不会起到约束的作用。 所以,使用submit时需要验证请加 return true或false.
例:<input type="submit" name="Submit" value="注 册" onClick=" return check();">
,在JS中判断的时候 写return true; 或者 return false;
但提到了form的写法:
type="submit"
<form id="frm1" action="<%=request.ServerVariables("Script_Name")%>"
method="post" onSubmit="return check_submit(this)">
<input id="btnconfirm" type="submit" value="确定" name="btnconfirm"></form>
<input type="submit" name="b1" value="提交" onClick="bt_submit_onclick()">
执行完onClick,转到action。可以自动提交不需要onClick,所以说onclick这里可以不要。
2. action和onSubmit的区别
form表单中action和onsubmit的表单检查区别 - Lai18.com IT技术文章收藏夹
onsubmit和action两个都是提交时触发的不过:onsubmit是在表单中的确认按钮被点击时触发的,一般是js函数,而action是在按钮被点击之后触发的,一般是触发前台提交到后台的请求,而引起后台的回应。
3. get和post的区别
Tutorial — Bottle 0.13-dev documentation
The action attribute specifies the URL that will receive the form data. method defines the HTTP method to use (GET or POST).
With method="get" the form values are appended to the URL and available through BaseRequest.query as described above. This is considered insecure and has other limitations, so we use method="post" here. If in doubt, use POST forms.
4.数字形式的时间转为时间格式
#!/usr/bin/python
import time
struct_time = time.strptime("30 Nov 00", "%d %b %y")
print "returned tuple: %s " % struct_time
格式符意义:
%a - abbreviated weekday name
%A - full weekday name
%b - abbreviated month name
%B - full month name
%d - day of the month (01 to 31)
%H - hour, using a 24-hour clock (00 to 23)
%I - hour, using a 12-hour clock (01 to 12)
%M - minute
%y - year without a century (range 00 to 99)
5. baby页面
html文件中,
<form action="/baby.html" method="GET">
方法定为GET。
main.py中,
@app.route('/baby.html', method='GET')
方法定为GET。
运行500错误:
原因是加号不能用在这里。
之前只看到405或500,没发现问题代码。
加上str()转换,代码改为:
birthtime = time.strptime(str(request.forms.get('date'))+'/'+str(request.forms.get('month'))+'/'+str(request.forms.get('year')), "%d/%m/%Y")
500错误为:
查看striptime的文档:
time.striptime(string[, format])
参数要求是string。现在str()转换出来的被系统认为是none。
绕过这个问题,代码改为:
birthtime = time.strftime("%d/%m/%Y %H:%M:%S")
现在问题代码是:
data = name.decode('utf-8'), gender.decode('utf-8'), birthtime.decode('utf-8')
500提示是:
再绕过去,代码改为:
data = name, gender, birthtime
界面不再500.
打开baby页面,填入信息,打印信息刚出现即消失。可以看到打印出来的信息是:
none,none,(当前时间)
打印信息还可以看到的问题是:这里的打印方法用了和打印记录相同的方法,但是现在只录入一个宝宝,不应该有多行记录。应该是录入一次信息后,后来都变成修改模式保存最新。
这说明不但birthtime的写法被认为是none,连界面读取出来的text也被认为是none。
另外,由于baby页面是get方法,所以可以看到不再500之后的baby页面网址:
所填参数悉数体现在url中。
执行python脚本时,返回:AttributeError: 'NoneType' object has no attribute 'opensession',原因?百度知道
这里说:
NoneType的本意是 (变量的值是)空的值.所以,值都是空的了,当然没有相关的各种属性
所以name和gender可能没有收到传值,所以是none。但是为什么又已经被get到了url中了呢?
重新考虑一下,在刚刚打开baby页面时,确实这些值都是none。而现在程序走的顺序是:先确认这些值不是none,才允许打开页面,再输入。应该做到让baby页面打开时,不去碰这一段代码,直接打开。
在首页,首先用get方法打开的是“/”页面,然后采用post方法打开并返回“/index”,运行和输入数据相关的save函数。所以打开“/”时,不会产生任何none类错误。
12.23问教练:
输入无法传递到数据库(none,none,none)里去,归根结底还是method。
观察已经成功接受数据并显示数据的/页面和/history.html,/的method是get,/index的method是post,/history的method是get。/页面管数据输入,接受键盘敲入数据,/history管数据输出,从数据库里读出来显示在页面上。这里的/index.html如果独立在url中打出来,就显示405方法错误。如果把/index的方法改为get,数据输入回车后,马上就返回这个错误的405index页面,这时history就无法接受到数据了,因为中间错误导致数据没有进入数据库。
在7w作业里,没有history页面,/输入后,在index页面输出结果。方法是:负责输入的/是get,负责输出的/index是post。
这两个成功案例,/和/index居然是两个页面,可以用两个方法,让我觉得根目录/是个逆天的神奇存在。
现在在baby项目里,baby页面需要负责输入,所以方法是get,同时它还要负责输出。结果就是从baby页面的输入框输入的内容,不能被正确存储到数据库里,从而导致页面也不能输出正确的内容。因为方法是get,所以输入内容可以在url中看到。
为什么url都能接受的内容,就没有正确进入数据库呢?感觉这个和用了submit还是用了button的关系不大。submit在这里的作用就是提交form。用不用submit,url都已经获得了这个输入内容,它只是没有进入数据库,或者说它总是把空数据传入数据库。
之所以会插入js,是因为我觉得这个页面需要这样一个交互效果:addnew按钮要把填写宝宝信息数据的表单显示出来,填完表单数据后提交,又需要返回刚刚填入的宝宝信息数据。并且为了可修改,还需要返回一个修改按钮(setting)。这三个按钮:addnewbaby,savebaby,setting,唯一涉及到提交表单的就是savebaby,所以它是submit。但是设它为submit后,返回的内容一闪而过。改为button则不会。除了一闪而过外,submit可以直接enter提交,而button不会,这也是它们的主要区别。在这里,都没有解决为什么会传空数据给数据库的问题。
我能想到的可能因素就是页面的方法和按钮的type,但是对其中的道道和所以然很模糊。
猜测如果有一个地方,能让baby.html在接受了数据后方法变成post的话,这事儿就成了。
刚才说的所有method,都是在main.py中。
现在把baby.html里form的方法,从get改为post。main.py里,在原来的点击baby方法get之下,又写了一个路由,方法post,函数就是savebaby搬下来。运行结果是:提交后500错误,命令行端没有提示。但是查看baby数据库,发现输入内容读进数据库里了。不再none了。
手机端有500提示(电脑版qpython没有):
Bottle v0.13-dev server starting up (using MyWSGIRefServer())... Listening on http://localhost:8800/ Hit Ctrl-C to quit.
localhost - - [23/Dec/2015 15:44:38] "HEAD / HTTP/1.1" 200 0
localhost - - [23/Dec/2015 15:44:38] "GET / HTTP/1.1" 200 4408
localhost - - [23/Dec/2015 15:44:42] "GET /baby.html HTTP/1.1" 200 5884
Traceback (most recent call last):
File "/storage/emulated/0/com.hipipal.qpyplus/lib/python2.7/site-packages/bottle.py", line 850, in _handle
return route.call(**args)File "/storage/emulated/0/com.hipipal.qpyplus/lib/python2.7/site-packages/ bottle.py", line 1721, in wrapper
rv = callback(a, *ka)File "/storage/emulated/0/com.hipipal.qpyplus/projects/babyrecord/main.py", line 107, in savebaby
createbaby(data)File "/storage/emulated/0/com.hipipal.qpyplus/projects/babyrecord/main.py", line 72, in createbaby
cursor.execute('insert into babyinfo (name, gender, birthtime) values (?,?,?)', data)ProgrammingError: You must not use 8-bit bytestrings unless you use a text_factory that can interpret 8-bit bytestrings (like text_factory = str). It is highly recommended that you instead just switch your application to Unicode strings.
localhost - - [23/Dec/2015 15:45:07] "POST /baby.html HTTP/1.1" 500 750
把baby.db删除,重新运行程序,然后查看新生成的baby.db,发现其中有两行数据:
第一行none数据,应该就是还不能把decode放出来的原因。不能把decode放出来又造成了上面这个500错误中说的“You must not use 8-bit bytestrings”。
python - pysqlite insert unicode data 8-bit bytestring error - Stack Overflow
That is one of the most helpful error messages that I've ever seen. Just do what it says. Feed it unicode objects, not UTF-8-encoded str objects. In other words, lose the .encode('utf-8') or maybe follow that later by decode('utf-8')
练习if-else:
代码修改:
@app.route('/baby.html', method='GET')
def baby():
babylabel=savebaby()
print babylabel
if babylabel ==None:
return template(ROOT+'/baby.html')
@app.route('/baby.html', method='POST')
def savebaby():
name = request.forms.get('name')
gender = request.forms.get('gender')
birthtime = time.strftime("%d/%m/%Y %H:%M:%S") #time.strptime(str(request.forms.get('date'))+'/'+str(request.forms.get('month'))+'/'+str(request.forms.get('year')), "%d/%m/%Y")
# data = name.decode('utf-8'), gender.decode('utf-8'), birthtime.decode('utf-8')
if name==None or gender==None or birthtime==None:
return None
else:
data = name, gender, birthtime.decode('utf-8')
createbaby(data)
return readbaby()
运行结果:
页面500,终端提示信息为:
在reture语句中加入babylabel = ''
可以点开baby.html了。
@app.route('/baby.html', method='GET')
def baby():
babylabel = savebaby()
print babylabel
if babylabel == None:
return template(ROOT+'/baby.html', babylabel='')
继续运行,输入baby信息,500错误:
none输出了两遍,到post时500了。
补充完整的print变量语句:
def baby():
babylabel = savebaby()
print 'babylabel is: %s'%(babylabel)
……
def savebaby():
name = request.forms.get('name')
print 'name is: %s'%(name)
gender = request.forms.get('gender')
print 'gender is: %s'%(gender)
运行结果为:
到post出错,想起来到了baby信息填完后,没有返回baby页面。
代码改为:
else:
data = name, gender, birthtime.decode('utf-8')
createbaby(data)
return template(ROOT+'/baby.html', babylabel=readbaby())
再运行,确实通过了:
运行,baby2页面无内容。单独打开baby2,也没有内容。
把babylabel和按钮setting从div2中放出来,有了。