I'm trying to produce a simple web form using CherryPy in Python 3.5 (to compare with an sqlite3 database) which takes a few inputs of different types of data. When the checkboxes are left unticked, it produces an error as (i assume) there is no default null value; it is either 'on' or nonexistant. How can I change my form so that it autommatically sets empty boxes to 'None'? Here is the code (section):
class startScreen(object):
@cherrypy.expose
def index(self):
return """<form method="post" action="search">
Job Title:<br>
<input type="text" name="title"><br>
Employer name:<br>
<input type="text" name="employer"><br>
Minimum Starting Salary:<br>
<input type="number" name="minsal"><br>
Contract Hours Per Week:<br>
<input type="number" name="hpwMin">
<input type="number" name="hpwMax"><br>
Start Date:<br>
<input type="date" name="startDate"><br>
<!--jobtype drop down menu--!>
Contract Length (months):<br>
<input type="number" name="CLMin">
<input type="number" name="CLMax"><br>
<!--qualifications list--!>
<!--key skills list--!>
Training Offered:<br>
<input type="checkbox" name="training"><br>
Expenses covered:<br>
<input type="checkbox" name="expenses"><br>
Job benefits:<br>
<input type="checkbox" name="benefits"><br>
Number of days annual holiday: <br>
<input type="number" name="holiday"><br>
Opportunities abroad:<br>
<input type="checkbox" name="abroad"><br>
Date posted: <br>
<input type="date" name="datePosted"><br>
<button type="submit">Submit</button>
</form>
"""
@cherrypy.expose #needed for every page
def search(self, title, employer, minsal, hpwMin, hpwMax, startDate, CLMin, CLMax, training, expenses, benefits, holiday, abroad, datePosted):
search.search.searchDBS(title, employer, minsal, hpwMin, hpwMax, startDate, CLMin, CLMax, training, expenses, benefits, holiday, abroad, datePosted)
return "done"
This is the output on the webpage when the one tickbox is unchecked:
404 Not Found
Missing parameters: training
Traceback (most recent call last):
File "C:\Users\Anna\AppData\Local\Programs\Python\Python35\lib\site-packages\cherrypy\_cpdispatch.py", line 60, in __call__
return self.callable(*self.args, **self.kwargs)
TypeError: search() missing 1 required positional argument: 'training'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\Anna\AppData\Local\Programs\Python\Python35\lib\site-packages\cherrypy\_cprequest.py", line 670, in respond
response.body = self.handler()
File "C:\Users\Anna\AppData\Local\Programs\Python\Python35\lib\site-packages\cherrypy\lib\encoding.py", line 221, in __call__
self.body = self.oldhandler(*args, **kwargs)
File "C:\Users\Anna\AppData\Local\Programs\Python\Python35\lib\site-packages\cherrypy\_cpdispatch.py", line 66, in __call__
raise sys.exc_info()[1]
File "C:\Users\Anna\AppData\Local\Programs\Python\Python35\lib\site-packages\cherrypy\_cpdispatch.py", line 64, in __call__
test_callable_spec(self.callable, self.args, self.kwargs)
File "C:\Users\Anna\AppData\Local\Programs\Python\Python35\lib\site-packages\cherrypy\_cpdispatch.py", line 163, in test_callable_spec
raise cherrypy.HTTPError(404, message=message)
cherrypy._cperror.HTTPError: (404, 'Missing parameters: training')
That's the regular behavior of the html checkboxes, you can handle that with a default argument: training=None
or use kwargs and look for the key.
For the first option, your expose method would be:
@cherrypy.expose #needed for every page
def search(self, title, employer, minsal, hpwMin, hpwMax,
startDate, CLMin, CLMax, expenses,
benefits, holiday, abroad, datePosted, training=None):
# "training" will be None, if the checkbox is not set
# you can verify with something like:
# if training is None:
# ...
search.search.searchDBS(
title, employer, minsal, hpwMin, hpwMax,
startDate, CLMin, CLMax, training, expenses,
benefits, holiday, abroad, datePosted)
return "done"
Another alternative (better from my perspective, because those are a lot of parameters for a method, you can use the **params
alternative:
@cherrypy.expose #needed for every page
def search(self, **params):
fields = ['title', 'employer', 'minsal', 'hpwMin',
'hpwMax', 'startDate', 'CLMin', 'CLMax',
'training', 'expenses','benefits', 'holiday',
'abroad','datePosted']
# the params.get, will try to get the value if the field
# and if is not defined, then it will return None
search.search.searchDBS(*[params.get(f, None) for f in fields])
# alternative approach without passing specific fields
#if 'training' not in params:
# params['training'] = None
#search.search.searchDBS(**params)
return "done"