web.py is a Python web framework that is as simple as it is powerful.
Visit http://webpy.org for more information.
To install web.py, please run:
python3 -m pip install web.py
web.py is a web framework for python that is as simple as it is powerful.
Home Page: http://webpy.org
License: Other
web.py is a Python web framework that is as simple as it is powerful.
Visit http://webpy.org for more information.
To install web.py, please run:
python3 -m pip install web.py
web/contrib/template.py has this logic:
if self._type == "text":
...
else:
cls = None
type = None ##
...
if type:
return stream.render(type)
On the line where I put the ##, it should say type=self._type. Currently, calling render_genshi(type='html') and render_genshi(type='xhtml') do the exact same thing, which seems like a mistake. (For the record, the current code is always picking xhtml.)
multiple_insert is supposed to be a faster way to add things to the database, but it does a lot of string concatenation and object creation and concatenation, which is very slow. It should be optimized to reduce these.
session.request_token = '123'
raise web.redirect('http://example.com/oauth')
This code must set session cookie with redirect response. But it doesn't do.
Session cookies are assuming that the app runs on a domain's or subdomain's root.
The cookie path should be set according to
os.environ['REAL_SCRIPT_NAME']
This raises UnicodeDecodeError:
test.py:
import web, os
render = web.template.render(os.path.abspath(os.path.dirname(__file__)))
render.test()
test.html:
$var array = [u"один", u"два", u"три"]
$ test = u"один"
<p>just a test</p>
To fix it I had to change line 1011 in _load_template in template.py to this:
return Template(open(path).read().decode("utf-8"), filename=path, **self._keywords)
Cannot email html message.
If I set "Content-Type: text/html" header it simply appends it to default "text/plain", resulting two "Content-type" headers in the same message.
eg
Content-Type: text/plain; charset="utf-8"
Content-Type: text/html; charset=UTF-8
And message is treated as text/plain, but i need it to be html.
Sending email with "Content-type: multipart/alternative" (with text and html messages) is also impossible, since when I include html message as attachment, it automatically sets "Content-type: multipart/mixed" and my html message becomes attachment.
>>> import web; db = web.database(dbn='postgres', db='template1')
>>> db.select('dual', where="foo like 'foo%'")
ERR: SELECT * FROM calls WHERE foo like 'foo%'
Traceback (most recent call last):
...
IndexError: list index out of range
This should work, but doesn't since it tries to interpolate the string. Instead I use this workaround:
db.select('calls', where="foo like 'foo%%'")
but web.py should do that automatically, since that's totally unintuitive.
WARNING: Fixing this will probably break the workaround, which means it's a backwards-incompatible change. On the other hand, I think SQL treats % the same as %% in most cases, so it's probably not a huge deal.
http://webpy.org/install has a link to http://webpy.org/tutorial2 which then tells you that page is out of date and points you towards the 0.3 version of the tutorial.
Aaron suggested that we should add a secure
option to sessions.
Hi,
I am using web.py as an embedded webserver in my app. Because there is no way to set the port served programatically I have to do this
import sys; sys.argv[1] = '8080' #Yuck
self.app = web.application(xxxx)
thread.start_new_thread(self.app.run, ())
Otherwise webpy assumes the first command line argument it its port (which it is not as my app has many other command line args)
DB insert with no values doesn't work with mysql, even though it works with sqlite.
>>> db.insert("mytable")
ERR: INSERT INTO mytable DEFAULT VALUES
The correct syntax for MySQL is:
INSERT INTO mytable () VALUES();
(Originally reported by Ole Trenner in the mailing list.)
The "More..." link in the top-right corner of webpy.org is broken.
Today I'm update my Debian server and got the error:
Traceback (most recent call last):
File "/usr/lib/pymodules/python2.6/web/wsgiserver/__init__.py", line 1174, in communicate
req.respond()
File "/usr/lib/pymodules/python2.6/web/wsgiserver/__init__.py", line 544, in respond
self._respond()
File "/usr/lib/pymodules/python2.6/web/wsgiserver/__init__.py", line 556, in _respond
response = self.wsgi_app(self.environ, self.start_response)
File "/usr/lib/pymodules/python2.6/web/httpserver.py", line 237, in __call__
return self.app(environ, xstart_response)
File "/usr/lib/pymodules/python2.6/web/httpserver.py", line 212, in __call__
return self.app(environ, start_response)
File "/usr/lib/pymodules/python2.6/web/httpserver.py", line 237, in __call__
return self.app(environ, xstart_response)
File "/usr/lib/pymodules/python2.6/web/application.py", line 293, in wsgi
start_resp(status, headers)
File "/usr/lib/pymodules/python2.6/web/httpserver.py", line 233, in xstart_response
out = start_response(status, response_headers, *args)
File "/usr/lib/pymodules/python2.6/web/httpserver.py", line 234, in xstart_response
self.log(status, environ)
File "/usr/lib/pymodules/python2.6/web/httpserver.py", line 251, in log
print >> outfile, utils.safestr(msg)
AttributeError: 'str' object has no attribute 'write'
It's just when I run application.
When I'm use request emulation, it's okay.
There's a bug in the Radio widget. Both (value, description) is set as its value. This is trivial to fix. Here is a patch:
http://dpaste.com/hold/266757/
The NotFound and InternalError handlers are special... which is confusing when you want to use some of the other error handlers (like Forbidden or Unauthorized) in the same way.
I propose making them all a little more uniform. Here's an untested patch to illustrate my intent:
http://pastebin.com/TgB6LH5q
When the db module constructs a delete query with the USING keyword, the USING clause is appended after the WHERE clause. Not sure if this valid for other flavors of SQL, but it is against MySQL syntax.
For instance the following code:
web_app.bootleg.bootlegdb.delete('feature_mapping',
using='feature_mapping,attributes',
where='feature_mapping.attribute_id=attributes.attribute_id AND '
'feature_mapping.feature=$feature AND '
'attributes.attribute_name IN $attributes',
vars={'feature': feature,
'attributes': attributes})
Will generate the following query:
DELETE FROM feature_mapping WHERE feature_mapping.attribute_id=attributes.attribute_id AND feature_mapping.feature='fozzie_spam' AND attributes.attribute_name IN ('FB_SUSPECT_1_06') USING feature_mapping,attributes
This results in a syntax error. Simply putting the USING clause before the WHERE clause solves the issue.
Right now using memoize with background=True, if you ask for a result that's expired, it'll recalculate it in a new thread but send you the old result. It'd be nice if there was an option to have an ongoing thread that would recalculate the answer just before it expired.
I used this example code to reproduce the error:
# in the forms.py
result = data.all_categories() # this method return all records of table category in GAE/big table format.
args = [(row.key().id(), row.title) for row in result]
new_post = form.Form(
form.Dropdown('category', args),
form.Textbox('title'),
form.Textarea('text'),
form.Dropdown('language', [('pt', 'Portuguese'), ('en',
'English')]),
form.Button('Submit!')
# in code.py
class Post:
def GET(self):
frm = forms.new_post()
return render.full(render.form(frm))
def POST(self):
global last_updated
frm = forms.new_post()
if frm.validates(): # in this point the error.
data.save_entry(frm.d)
last_updated = data.last_updated()
raise web.seeother('/')
else:
return render.full(render.form(frm))
IMHO the root cause of the problem is the 'big table' format, I say this because the form generated by the GET method is correct(It has the Category A, Category B) but when I submit the form and the forms.validates() is called the error occurs.
The problem is in the forms.py in this function:
def attrget(obj, attr, value=None):
if hasattr(obj, 'has_key') and obj.has_key(attr): return obj[attr]
if hasattr(obj, attr): return getattr(obj, attr)
return value
generate this error:
<type 'exceptions.AttributeError'>: 'unicode' object has no attribute
'has_key'
args = ("'unicode' object has no attribute 'has_key'",)
message = "'unicode' object has no attribute 'has_key'"
Problem is in change
http://github.com/webpy/webpy/commit/84205cf4a0495ec5a10cb2d6d9904262d9e7ad68
This change results in such a template:
from web.template import CompiledTemplate, ForLoop, TemplateResult
import snippets
# encoding: utf-8
join_ = main._join; escape_ = main._escape
def main (username):
__lineoffset__ = -4
loop = ForLoop()
self = TemplateResult(); extend_ = self.extend
extend_([u'\n'])
extend_([u'<tr>\n'])
extend_([u' <td/><td colspan="2">Hello, ', escape_(username, False), u'!</td><td/>\n'])
extend_([u'</tr>\n'])
return self
main = CompiledTemplate(main, './templates/main.html')
# encoding: utf-8
join_ = time_reports_individual._join; escape_ = time_reports_individual._escape
def time_reports_individual (periods):
...
And exception:
join_ = main._join; escape_ = main._escape
^
IndentationError: unexpected indent
Instead this should look as this IMHO:
code = code.replace("__template__", name, 1)
out.write(code)
out.write('\n\n')
out.write('%s = CompiledTemplate(%s, %s)\n\n' % (name, name, repr(path)))
# inject "join_ = ..; escape_ = .." into the code..
# That is required to make escape functionality work correctly.
out.write('\njoin_ = %s._join; escape_ = %s._escape\n' % (name, name))
Automatic forms should create a more CSS friendly and contemporary HTML. For example <li>
-Elements with <label>
s and <input>
-Elements.
Another interesting feature could be automatic ids generated from the input's name, like
<li id="prefix-username">
<label for="username_generated_element">Name of the User</label>
<input id="username_generated_element" type="text" name="username">
</li>
With an optional prefix this could greatly ease CSS styling.
The send logic should be pulled out so it can be applied to a message from anywhere. And if _EmailMessage is going to have all those features they ought to be public. (Or was it just copied from the Email module?)
Reported on Launchpad by by Brian J Ewing on 2010-11-08.
https://bugs.launchpad.net/webpy/+bug/672538
db.query("INSERT INTO table1 (field1, field2) VALUES ('value', 'value');" +
" UPDATE table2 SET foo='bar'")
This works fine, however a _mysql_exceptions.ProgrammingError
is raised:
_mysql_exceptions.ProgrammingError: (2014,
"Commands out of sync; you can't run this command now")
in <bound method Cursor.__del__ of <MySQLdb.cursors.Cursor object at 0x>>
db.query tries to return the result from the last query without first freeing the result of the first, and MySQLdb raises this exception
Between .32 and .33, submit buttons no longer have text. We use the description variable, but its cleared out on instantiation. I have attached a patch to fix carry the value attribute to the tag rendering,
diff --git a/web/form.py b/web/form.py
index 750fe6f..8cb7a1c 100644
--- a/web/form.py
+++ b/web/form.py
@@ -312,7 +312,8 @@ class Button(Input):
def render(self):
attrs = self.attrs.copy()
attrs['name'] = self.name
return '<button %s>%s</button>' % (attrs, self.description)
attrs['value'] = self.value
return '<button %s>%s</button>' % (attrs, self.value)
class Hidden(Input):
"""Hidden Input.
Bug reported in Launchpad.
https://bugs.launchpad.net/webpy/+bug/598080
Although UPDATE ... SET ... ORDER BY .... is valid SQL, current db module doesn't support this. Current documentation shows arguments for db.select works for db.update, and there's no mention about order is not working in update.
Supposed to be work:
ret = self.db.update('Articles', vars = val,
where = 'bSerial = $board_id AND aIndex >= $index',
order = 'aIndex DESC',
aIndex = web.SQLLiteral('aIndex + 1'))
Result:
ERR: UPDATE Articles SET order = 'aIndex DESC', aIndex = aIndex + 1
WHERE bSerial = 1371L AND aIndex >= 48L
Finally:
ProgrammingError: (1064, "You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version for
the right syntax to use near 'order = 'aIndex DESC', aIndex = aIndex + 1
WHERE bSerial = 1371 AND aIndex >= 48' at line 1")
The current reloader tries to reload modules, it doesn't work well if there is some global state. Things like sessions etc. are not working with the reloader.
We need a new reloader that restarts the whole process when it detects file changes.
Cf: http://groups.google.com/group/webpy/browse_thread/thread/ea49983d0d839fa6?pli=1
from web import form
from web.utils import storify
f = form.Form(
form.Checkbox('contact_me', checked=True,
description='spam_me')
)
f.fill(kw=dict()) # no adding.
assert '''checked="checked"''' in f.render()
f = form.Form(
form.Checkbox('contact_me', checked=False,
description='spam_me')
)
f.fill(kw=dict()) # no adding.
assert '''checked="checked"''' not in f.render()
f.fill(kw=dict(contact_me=True)) # add it.
assert '''checked="checked"''' in f.render(), "didn't fill in"
'fill' is just a shorthand to 'valididates()', which doesn't know how
to
do much except set the 'value' attribute.
I observe in my tests that indeed, submitted forms don't "stay"
checked. Validators just seem to look at the 'value' attribute, and
that is it. (cf. the _validate method).
The hackish solution is to wire in that "checked means value is valid"
thing yourself. Ugly though!
I only have pgdb installed on my system and I can't use Postgrès with web.db.
I get the following exceptions:
File "/usr/lib64/python2.6/site-packages/web/db.py", line 918, in _connect
conn.set_client_encoding('UTF8')
AttributeError: 'pgdbCnx' object has no attribute 'set_client_encoding'
Indeed, pgdb module doesn't provide this method or any equivalent.
Here's a patch for the db.py file that works at home, I think it will preserve the behavior for psycopg* users. I did'nt figure out how to know which module in the was used in the _connect contexte, so I exploited the AttributeError exception to call the correct method.
918c918,921
< conn.set_client_encoding('UTF8')
---
> try:
> conn.set_client_encoding('UTF8')
> except (AttributeError):
> conn.cursor().execute("set client_encoding to 'UTF-8'")
There's the same issue with _connect_with_pooling, but I didn't meet her ;)
Have a nice day :)
I had an unexpected behavior while I had a form page and my controller had POST method, but it just redirected to another page.
It looked something like:
class foo:
def POST(self):
raise web.seeother('/bar')
and when I wrote something like:
class foo:
def POST(self):
form = web.input(somefield={})
raise web.seeother('/bar')
it worked!
Too strange. Please, take a look at it.
0.34 appears to be sensitive to whitespace before continue or break statements in templates. When I leave out the whitespace (which is the style used in the Templating section of the tutorial):
$def with (requests, errmsg)
$var title: Test
$ contacts = ['Craig', '', 'Jay']
$for (i, contact) in enumerate(contacts):
$if contact == '':
$continue
Contact $i: $contact
I get this error:
TypeError: emit() takes exactly 2 arguments (3 given)
The error goes away if there is a blank between the '$' and the continue.
Form class is not new-style class. I was trying to call super(MyForm, self).__init__(*inputs)
in my custom form class but no success since super()
only works for new-style classes.
Form class should be defined as follow
class Form(object):
instead of class Form:
Cannot get error display correctly, check this test case
# coding: utf-8
import web
urls = (
'/(.*)', 'hello'
)
app = web.application(urls, globals())
class hello:
def GET(self, name):
a = u"ошибка" # if remove this line and coding declaration—then everything is fine
raise Exception("test")
if __name__ == "__main__":
app.run()
Most of the time i get this in the browser instead of pretty djangoerror:
Traceback (most recent call last):
File "/Library/Python/2.6/site-packages/web/wsgiserver/__init__.py", line 1174, in communicate
req.respond()
File "/Library/Python/2.6/site-packages/web/wsgiserver/__init__.py", line 544, in respond
self._respond()
File "/Library/Python/2.6/site-packages/web/wsgiserver/__init__.py", line 558, in _respond
for chunk in response:
File "/Library/Python/2.6/site-packages/web/utils.py", line 353, in safestr
return str(obj)
File "/Library/Python/2.6/site-packages/web/template.py", line 1260, in __str__
return self["__body__"].encode('utf-8')
File "/Library/Python/2.6/site-packages/web/template.py", line 1253, in __getitem__
self["__body__"] = u"".join(self._data)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd0 in position 19: ordinal not in range(128)
Traceback (most recent call last): File "/Users/bonkabonka/pypy-1.3/site-packages/web/wsgiserver/__init__.py", line 1174, in communicate req.respond() File "/Users/bonkabonka/pypy-1.3/site-packages/web/wsgiserver/__init__.py", line 544, in respond self._respond() File "/Users/bonkabonka/pypy-1.3/site-packages/web/wsgiserver/__init__.py", line 556, in _respond response = self.wsgi_app(self.environ, self.start_response) File "/Users/bonkabonka/pypy-1.3/site-packages/web/httpserver.py", line 201, in __call__ return self.app(environ, xstart_response) File "/Users/bonkabonka/pypy-1.3/site-packages/web/application.py", line 273, in wsgi self.load(env) File "/Users/bonkabonka/pypy-1.3/site-packages/web/application.py", line 372, in load ctx[k] = safeunicode(v) AttributeError: ThreadedDict instance has no attribute '__setitem__'
When using subapplications regexes, the top level url definitions behave differently then regexes in subapplications. This is an example based on code in http://webpy.org/cookbook/subapp.
blog.py:
import web urls = ( "", "reblog", "/(blog|Blog)", "blog" #change from original ) class reblog: def GET(self): raise web.seeother('/') class blog: def GET(self, path): return "blog " + path app_blog = web.application(urls, locals())
code.py
import web import blog urls = ( "/(blog|Blog)", blog.app_blog, #change from original # "/blog", blog.app_blog, "/(.*)", "index" ) class index: def GET(self, path): return "hello " + path app = web.application(urls, locals()) if __name__ == "__main__": app.run()
The regex /(blog|Blog) is the same in blog.py and code.py however request GET http://localhost:1111/blog/Blog does not return the expected result. If the regex is commented out in code.py and replaced with the line below it GET request returns an expected result.
Try to run this code:
# coding: utf-8
import web
from web import form
urls = (
'/(.*)', 'hello'
)
app = web.application(urls, globals())
testForm1 = form.Form(form.Textbox("test", description=u"Тест", pre='Еще')) # works
testForm2 = form.Form(form.Textbox("test", description=u"Тест", pre=u'Еще')) # raises error
class hello:
def GET(self, name):
return testForm2.render()
if __name__ == "__main__":
app.run()
After commit 9e927c4, I found web.session will app.add_processor(self._processor) on each request, cause session set-cookie multi times.
Here's the playback:
import web
web.config.debug = False
urls = (
"/count", "count",
"/reset", "reset"
)
app = web.application(urls, locals())
session = web.session.Session(app, web.session.DiskStore('sessions'), initializer={'count': 0})
class count:
def GET(self):
session.count += 1
return str(session.count)
class reset:
def GET(self):
session.kill()
return ""
if __name__ == "__main__":
app.run()
cat@cat-mbp ~/i(master) $ ./app.py
init session here
http://0.0.0.0:8080/
cat@cat-mbp ~/i(master) $ curl -I http://localhost:8080/count
HTTP/1.1 200 OK
Set-Cookie: webpy_session_id=7e550992eff539cb17ce03484f25f38be9ef525b; Path=/; httponly
Connection: close
Date: Thu, 24 Feb 2011 10:14:40 GMT
Server: CherryPy/3.1.2 WSGI Server
cat@cat-mbp ~/i(master) $ curl -I http://localhost:8080/count
HTTP/1.1 200 OK
Set-Cookie: webpy_session_id=b8fd314485ae4012eae8bb098a1b9efebd5f6a68; Path=/; httponly
Set-Cookie: webpy_session_id=b8fd314485ae4012eae8bb098a1b9efebd5f6a68; Path=/; httponly
Connection: close
Date: Thu, 24 Feb 2011 10:14:40 GMT
Server: CherryPy/3.1.2 WSGI Server
cat@cat-mbp ~/i(master) $ curl -I http://localhost:8080/count
HTTP/1.1 200 OK
Set-Cookie: webpy_session_id=59f233edc5da2037e88e7a7292e6069a84a591d7; Path=/; httponly
Set-Cookie: webpy_session_id=59f233edc5da2037e88e7a7292e6069a84a591d7; Path=/; httponly
Set-Cookie: webpy_session_id=59f233edc5da2037e88e7a7292e6069a84a591d7; Path=/; httponly
Connection: close
Date: Thu, 24 Feb 2011 10:14:41 GMT
Server: CherryPy/3.1.2 WSGI Server
cat@cat-mbp ~/i(master) $ ./app.py
init session here
http://0.0.0.0:8080/
cat@cat-mbp ~/i(master) $ curl -I http://localhost:8080/count
HTTP/1.1 200 OK
Set-Cookie: webpy_session_id=02da716a33a5c183a02935cd816965a92f9766a3; Path=/
Connection: close
Date: Thu, 24 Feb 2011 10:23:20 GMT
Server: CherryPy/3.1.2 WSGI Server
cat@cat-mbp ~/i(master) $ curl -I http://localhost:8080/count
HTTP/1.1 200 OK
Set-Cookie: webpy_session_id=281774011de60cb488f299488dea974f88bf9b04; Path=/
Connection: close
Date: Thu, 24 Feb 2011 10:23:21 GMT
Server: CherryPy/3.1.2 WSGI Server
cat@cat-mbp ~/i(master) $ curl -I http://localhost:8080/count
HTTP/1.1 200 OK
Set-Cookie: webpy_session_id=f109babbf69c6fe811fb9561ba0eeb69c9216da7; Path=/
Connection: close
Date: Thu, 24 Feb 2011 10:23:21 GMT
Server: CherryPy/3.1.2 WSGI Server
The reloader does not appear to reload external modules under lighttpd. The reloader works as expected under the dev server although you must ensure that the modules are imported as "import x" and not as "from y import x".
I've test the basic blog code example with a Sqlite3 database. But everytime it collapse when processing $datestr(post.posted_on).
I then read the webpy code, and it seems that the datestr() function cannot process Sqlite3's DATETIME field, Python's type() function regards it as a 'str'(or 'Unicode') type...
The following webpy form:
simple_form = form.Form(
form.Radio('sex',
[('xy', 'male'),('xx', 'female')],
description='Select your sex',
),
)
Generates:
male
female
Not the expected:
male
female
I think this patch will fix the problem:
--- form.py 2010-03-20 13:40:07.000000000 -0400
+++ form_update.py 2010-05-10 13:05:30.000000000 -0400
@@ -262,8 +262,8 @@
attrs = self.attrs.copy()
attrs['name'] = self.name
attrs['type'] = 'radio'
- attrs['value'] = arg
- if self.value == arg:
+ attrs['value'] = value
+ if self.value == value:
attrs['checked'] = 'checked'
x += '<input %s/> %s' % (attrs, net.websafe(desc))
x += ''
From: http://groups.google.com/group/webpy/browse_thread/thread/b1de272a051b8d41
Bug reported on Launchpad by Martin Janda on 2010-06-30.
https://bugs.launchpad.net/webpy/+bug/600164
web.db for postgresql writes the column names in SQL as:
INSERT INTO log_changes (action, user, time) VALUES ...
But what if the column name is from the keyword as a column 'user' in the example?
Solution is to add double quotes around column name. For example:
INSERT INTO log_changes ("action", "user", "time") VALUES ...
Yes, I know, now it can be solved by using web.db.query method.
Noticed some unicode errors in templates. Here is one template that fails.
$ x = "మెయిల్"
$x
A dynamic form class (that allows adding elements dynamically) would be nice:
class DynamicForm(web.form.Form):
def add_input(self, new_input):
list_inputs = list(self.inputs)
list_inputs.append(new_input)
self.inputs = tuple(list_inputs)
It can be used like this:
form = DynamicForm()
for k,v in some.items():
form.add_input(web.form.Checkbox(v, value=k))
In webpy .34 release.
When there are multiple <input type="file" name="fname"> with the same name, web.input(fname={}) only returns the last one.
This is also how:
<input type="file" multiple=""> submits it's files. (works in ff3.6 & recentish chrome/safari)
My fix for this is in utils.py storify() line 147: change
else:
value = value[-1]
TO:
elif not isinstance(defaults.get(key), dict):
value = value[-1]
Related Suggested Change:
I hate having todo: web.input(email=[], phone=[], userfile={}) to get lists when I have multiple form elements with the same name.
Why not be able to do something like this: web.input(_nolists=False) [I can't think of a good name] then in webapi.py input() line 278: add 1 line…
defaults.setdefault('_nolists', True)
and in utils.py storify() add:
_nolists = defaults.pop('_nolists')
… and ...
elif _nolists and not isinstance(defaults.get(key), dict):
value = value[-1]
That forces returning FieldStorage objects (instead of their .value) when you do web.input(_nolists=False). I think thats ok since everyone probably wants that with a long list of files.
Let me know what you think about something like that.
-hudlee [[email protected]]
Every time I search for WebPY documentation on google, I am linked to the correct page, but with a trailing slash. The docs only work without a trailing slash. Maybe add an optional trailing slash to the urls?
entities are not escaped in exception_type
string or any other variables, having the side effect of hiding some information when angle brackets are presents. here a fork from master with applied a patch.
When loading a web page on a secure http connection (https), web.ctx.homedomain
and web.ctx.protocol
still return 'http'.
When (re) rendering Dropdowns with multiple selects, one can only pass a single value:
fdSelect = form.Form( form.Dropdown('Fire', ['q', 'b', 'c'], form.notnull, **{'multiple': None, 'size': 2} ), ) fd.Fire.value = 'b' fd.render() works as expected: ...\n b\n c\n.... fd.Fire.value = ['a', 'b', 'c'] fd.render() does not select anything ...\n b\n c\n....
This patch seems to fix that behaviour:
--- form.py.orig 2011-01-28 11:24:58.080150680 -0600 +++ form.py 2011-01-28 11:28:59.346763259 -0600 @@ -240,8 +240,10 @@ else: value, desc = arg, arg - if self.value == value: select_p = ' selected="selected"' - else: select_p = '' + if (self.value is not None and value in self.value): + select_p = ' selected="selected"' + else: + select_p = '' x += ' %s\n' % (select_p, net.websafe(value), net.websafe(desc)) x += '\n'
In form.py
I find a bug:
262 attrs['value'] = arg #arg -> value 263 if self.value == arg: #arg -> value 264 attrs['checked'] = 'checked'
Reported on Launchpad by Hudson Lee on 2010-04-11.
https://bugs.launchpad.net/webpy/+bug/560278
In webpy .34 release.
When there are multiple <input type="file" name="fname">
with the same name, web.input(fname={})
returns only the last one.
This happens to be how: <input type="file" multiple="">
submits it's files.
(works in ff3.6 & recentish chrome/safari)
My fix for this is in utils.py storify() line 147: change
else:
value = value[-1]
TO:
elif not isinstance(defaults.get(key), dict):
value = value[-1]
Related Suggested Change:
I hate having todo: web.input(email=[], phone=[], userfile={})
to get lists when I have multiple form elements with the same name.
Why not be able to do something like this: web.input(_nolists=False)
[I can't think of a good name] then in webapi.py input() line 278: add 1 line…
defaults.setdefault('_nolists', True)
and in utils.py storify() add:
_nolists = defaults.pop('_nolists')
… and ...
elif _nolists and not isinstance(defaults.get(key), dict):
value = value[-1]
That forces returning FieldStorage objects (instead of their .value) when you do web.input(_nolists=False)
. I think thats ok for a long list of files. People usually need the file name in any case.
A cleaner way to add this might be an input() wrapper something like web.inputs() which always returns lists for fields with the same name.
Let me know what you think about something like that.
-hudlee [[email protected]]
If the value attribute of a dropdown or radio button element is set to an integer and validation of the form containing that element fails the element's state is lost in the redisplayed form.
If the following form was submitted with the textbox left blank and the first radio button selected the form displayed after validation would show an empty textbox and no radio button selected.
simple_form = form.Form(
form.Textbox('test',
form.notnull,
),
form.Radio('example',
[1,2,3,4],
)
)
I think this happens because the form post is u/str and thus the value checks fail. Maybe this could be fixed by converting the values to strings for the test of equality in the render functions for these elements.
243c243
< if self.value == value: select_p = ' selected="selected"'
---
> if self.value == str(value): select_p = ' selected="selected"'
266c266
< if self.value == arg:
---
> if self.value == str(arg):
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.