How to get all items in multi list in bottle? - python

I have a form that allows me to add to a multi list using js. I want to be able to post all the data in that list to my bottle server, but I am not able to get any of the data in there. How do I get all the items in my statement to be posted to server.py? How do I access this post data once it is posted?
Relevant code:
server.py:
#bottle.route('/saveList', method='POST')
def save_list():
forms = bottle.request.get('the_list')
print forms # returns 'None'
return bottle.redirect('/updatelist') # just redirects to the same page with a new list
list.tpl
<select multiple="multiple" id="the_list" name="the_list">
%for item in my_ list:
<option>{{item}}</option>
%end
</select>
EDIT:
I am trying to get the whole list, not just the selected values. The user adds to the multi by way of textfield, button, and JS; so I want to get all the values (or all the new values).
EDIT 2:
I used the answers provided along with some js to get the desired result:
$('.add_to_the_list').click(function (e) {
...
var new_item = $('<option>', {
value: new_item_str,
text: new_item_str,
class: "new_item" // the money-maker!
});
...
function selectAllNewItem(selectBoxId) {
selectBox = document.getElementById(selectBoxId);
for (var i = 0; i < selectBox.options.length; i++) {
if (selectBox.options[i].className === "new_item") { // BOOM!
selectBox.options[i].selected = true;
}
}
}
...
$('#submit_list').click(function (e) {
selectAllNewBG("the_list")
});

You were close; just try this instead:
all_selected = bottle.request.forms.getall('the_list')
You'll want to use request.forms and getall. request.forms returns a MultiDict, which is the appropriate data structure for storing multiple selected options. getall is how you retrieve the list of values from a MultiDict:
for choice in all_selected:
# do something with choice
or, more simply:
for selected in bottle.request.forms.getall('the_list'):
# do something with selected

To get multiple values back use .getall. Here is the code I was able use this with.
import bottle
#bottle.route('/saveList', method='POST')
def save_list():
forms = bottle.request.POST.getall('the_list')
print forms
return bottle.redirect('/updatelist')
#bottle.route('/updatelist')
#bottle.view('index')
def index():
return {}
bottle.run()
The HTML
<html>
<body>
<form method="post" action="http://localhost:8080/saveList">
<select multiple="multiple" id="the_list" name="the_list">
<option value="1">Item 1</option>
<option value="2">Item 2</option>
<option value="3">Item 3</option>
</select>
<input type="submit" />
</form>
</body>
</html>
The output to stdout looks like:
127.0.0.1 - - [22/Mar/2014 13:36:58] "GET /updatelist HTTP/1.1" 200 366
['1', '2']
127.0.0.1 - - [22/Mar/2014 13:37:00] "POST /saveList HTTP/1.1" 303 0
127.0.0.1 - - [22/Mar/2014 13:37:00] "GET /updatelist HTTP/1.1" 200 366
[]
First time selected two objects, second time didn't select any.

Related

IntegrityError at /update_order/ duplicate key value violates unique constraint "app_order_pkey".DETAIL: Key (id)=(54) already exists

I am getting the above error . This is my updateorder view:
def updateorder(request):
data = json.loads(request.body)
orderid = data['orderid']
status = data['status']
order, created=Order.objects.update_or_create(id=orderid, status=status)
return JsonResponse('Status was updated',safe=False)
and this is my js:
var updateBtns = document.getElementsByClassName('update-status')
for (i=0;i<updateBtns.length;i++){
updateBtns[i].addEventListener('click',function(){
var orderid=this.dataset.orderid
var updatestatus = document.getElementById(orderid);
var status = updatestatus.options[updatestatus.selectedIndex].value;
updateOrderStatus(orderid,status)
})
}
function updateOrderStatus(orderid,status){
console.log('User is logged In , sending data....')
var url = "/update_order/"
fetch(url, {
method:'POST',
headers:{
'Content-Type':'application/json',
'X-CSRFToken':csrftoken,
},
body:JSON.stringify({'orderid':orderid,'status':status})
})
.then((response) =>{
return response.json()
})
.then((data) =>{
console.log('data:',data)
location.reload()
})
}
What I am wanting to do is that I have a admin page for my website where i see all orders and I am wanting to from that page change the status of the order.
This is my selectbox for reference:
<select
name="dstatus" id="{{ord.id}}" class="updatestatus">
<option value="Preparing" id="Preparing" >Processing</option>
<option value="Out For Delivery" id="Out For Delivery">Out For Delivery</option>
<option value="Delivered" id="Delivered">Delivered</option>
<option value="Cancelled" id="Cancelled">Cancelled</option>
</select>
<button data-orderid={{ord.id}} class="btnabc btnabc-outline-cottgin update-status">update</button>
and this is my order mode:
class Order(models.Model):
customer=models.ForeignKey(Customer,on_delete=models.SET_NULL,null=True,blank=True)
status = (
("Preparing", "Preparing"),
("Delivered", "Delivered"),
("Out For Delivery", "Out For Delivery"),
("Cancelled","Cancelled")
)
status=models.CharField(max_length=20,blank=True,null=True,choices=status)
So my aim is that whenever from my page I change the status of order It changes in my database too. But its not happening and above error is coming.Please help me on how it can be solved
This is not how update_or_create works.
This method actually takes 2 dictionaries:
update_or_create(defaults=None, **kwargs)
The **kwargs are used to look up the object, and defaults is what will be updated if something matched the kwargs, if not, both dictionaries will be merged to create a new object.
order, created = Order.objects.update_or_create(id=orderid, status=status)
Here, you're looking for an order that has both id=orderid and status=status. Since you can't find one (because the id exists but with another status), you try to create it. And since the id is unique, it fails.
What you want to do instead is:
order, created = Order.objects.update_or_create(
id=orderid,
defaults=dict(status=status),
)

How do I get ID of a submit type button on its click in Python + HTML + web2py?

I am using WEB2PY framework
For example, I have a lot of submit type buttons on my webpage and when I click one I want to pass that specific clicked button ID from HTML to a Python variable.
Another problem is that when I use a Python variable inside of a SQlite insert statement then I am getting an error.
My HTML code:
<form method = "POST">
Case:
<input type="text" name="case_qty" value = 0><br>
Pcs:
<input type="text" name="pcs_qty" value= 0><br>
<button type="submit">Add to cart</button>
</form>
PYTHON CODE:
def fortune():
case = 0
pcs = 0
proddict = {}
productrows = db(db.products).select()
//my db contains product id & name
for x in productrows :
proddict[x.id]= x.product_name
if request.post_vars:
case = int(request.post_vars.case_qty)
pcs = int(request.post_vars.pcs_qty)
product= proddict[]//i want submitted button id number inside []
sql = "insert into cart(product_name,case_qty,pcs_qty)values(product,case,pcs)"
// another problem is when i use variable
//inside values i am getting error
r = db.executesql(sql)
return locals()

Get value of a form input by ID python/flask

How do you get the actual value of the input id after you send it in Flask?
form:
<form action="" method="post">
<input id = "number_one" type="text" name="comment">
<input type="submit" value = "comment">
</form>
like, what I am trying to say is when the form is sent (i.e. when you do this):
request.form.get("comment")
the value of the text field is passed. What I can't figure out is how to get the value of the id.
So, when the form is sent we could then tell from which form the info was coming from, because each form has a unique id. In this case the id is number_one.
So, how do we go about getting the actual literal value of the id and not the text input?
You can't. The id value is not part of the form data set sent by the browser.
If you need to identify the field, you'll have to either add the id to the input element name, or if the id is generated by Javascript code, perhaps store the information in an extra hidden field.
Adding the id to the name could be done with a delimiter perhaps:
<input id = "number_one" type="text" name="comment.number_one">
which would require you to loop over all form keys:
for key is request.form:
if key.startswith('comment.'):
id_ = key.partition('.')[-1]
value = request.form[key]
There is a one way to identify the fields and also multiple forms together....
use this
<input value = "1" type="hidden" name="my_id">
so at your view file you can retrieve this value.
my_id = request.form.get("my_id","")
print my_id
your output will be
1
you can also do this...
my_id = request.form.get("my_id","")
if my_id == "1":
** for example **
value = request.form.get("any_parameter_of_form","")

Python: "is not None" not working as expected

In a multi-page survey application I am creating I have a jQuery UI slider bar which is used to provide a rating for an image. This returns a numerical value to my Python/Django view which is stored in a list slider_DV_values
On a later Data Verification survey page the participant is given the opportunity via another jQuery slider bar to update the rating they assigned the image.
My issue is that the jQuery UI slider bar only returnes a numerical value if the participant changes it. Therefore the original rating is getting overwritten, with nothing, if the participant does not update it.
However if they do update their rating the new value is getting stored.
If I try
elif step == 13:
slider_value1 = self.request.POST.get('slider_value1')
print "This is slider_value1", slider_value1
if slider_value1 is not None:
slider_DV_values.pop(0)
slider_DV_values.insert(0, slider_value1)
The original values stored in slider_DV_values are still getting overwritten, with nothing.
I thought the is not None would have prevented an empty value from being used to overwrite the original value? IS this not correct?
Can anyone tell me how to prevent the original values from getting overwritten unless the new value is an updated numerical value?
Thanks, Deepend
EDIT
To see how I am getting my values this is the jQuery slider bar in a page of my SurveyWizardView the value of which is returned via the hidden form element
<div class="DV_image_row">
<div class="DV_image_left">
<img src="{% static "survey/images/pathone/" %}{{first_image}}{{fourth_image}}{{seventh_image}}" height="300" width="250" style="border:1px solid black;" align="middle"/>
<div class="DV_slider_one" id="one"></div>
<script >
$('#submit').click(function() {
var username = $('#hidden').val();
if (username == "") username = 0;
$.post('comment.php', {
hidden: username
}, function(return_data) {
alert(return_data);
});
});
$(".DV_slider_one").slider({
animate: true,
range: "min",
value: {{first_slider}}{{forth_slider}}{{seventh_slider}},
min: -100,
max: +100,
step: 1,
slide: function(event, ui) {
$("#slider-result_left").html((ui.value > 0 ? '+' : '') + ui.value);
if($(this).attr("id") == "one")
$("#hidden2").val((ui.value > 0 ? '+' : '') + ui.value);
}
});
</script>
<div id="slider-result_left">{{first_slider}}{{forth_slider}}{{seventh_slider}}</div>
<input type="hidden" name="slider_value1" id="hidden2"/>
</div>
"" is None is False
ONLY None is None is True
perhaps you just want if not slider_value1 : which is true for ANY falsey value (empty string,empty list, empty tuple, false, 0 , None , etc)
You might want to try the simple if slider_value1 != '' . This is a better option than if not slider_value1 because the latter will block out 0 also which you might not want to do.

How to compare posted webapp2 value to string in a form using %{name}s python

I'm a python newbie using wepapp2 as a standalone with python 2.7.5 and Mssql server express 2012.
For now, I'm trying to build a simple webpage for myself without a frame work. It's a form imported into a form handler. The handler uses string formatting to persist the form values when a required field is missing, but I'm having issues retaining values for select elements.
Debugging showed me that val type is 'str' and when outputted to HTML using %(status)r', the value was u'o', but the length of val equaled 10. I assume this is the reason why val == 'o' is false, but why? How may I get the conditional statements below to result True? Thanks.
formhandler.py
class TaskFormHandler(webapp2.RequestHandler):
def post(self):
...
col = self.request.get(field)
...
if error_flag:
self.write_display(error_flag,fields[0],...)
def write_display(self,error='',status='',...):
form_vals = {'error':error,'status':status,...}
self.response.write(webview.form % form_vals)
webview.py
from string import Template
val = '%(status)s'
if val == 'o':
params = dict(op1=' selected',op2='',op3='')
elif val == 'c':
params = dict(op1='',op2=' selected',op3='')
elif val == 'a':
params = dict(op1='',op2='',op3=' selected')
else:
params = dict(op1='',op2=' selected',op3=len(val))
template = Template("""
<label>Temp_Status
<select name='status'>
<option value='o'${op1}>Opened</option>
<option value='c'${op2}>Completed</option>
<option value='a'${op3}>Aged</option>
</select>
</label><br><br>
""")
form = """
<form method='post' action='/tasksystem/taskform'>
...
...
""" + template.substitute(params) + """
...
...
</form>
"""
This is the output from the webpage's page source:
<label>Temp_Status
<select name='status'>
<option value='o'>Opened</option>
<option value='c' selected>Completed</option>
<option value='a'10>Aged</option>
</select>
</label><br><br>
I dont know webapp2, but 10 is the length of %(status)s. Correct would be val = str(status) as the 1st line, I think. Or simply check for status == XX
After posting this new solution and comparing it to the old, I now believe the old
did not work because '%(status)s' was never used within the context of a string of text for substitution. As #Hendrik pointed out, it was literally being used as the string itself and failing because 'o'=='%(status)s' is false.
This explains why I saw the value in the webpage source with op1='%(status)s', because params was concatenated into the form text and rendered by the template class. Unbelievable! I hope this posting helps those looking for a pure python solution in retaining HTML SELECT element values without a framework. tx
formhandler.py
class TaskFormHandler(webapp2.RequestHandler):
...
def write_display(self,error='',status='',...):
if status == 'o':
op1,op2,op3 = ' selected','',''
elif status == 'c':
op1,op2,op3 = '',' selected',''
elif status == 'a':
op1,op2,op3 = '','',' selected'
else:
op1,op2,op3 = '','','selected'
form_vals = {'error':error,'status':status,'op1':op1,...}
self.response.write(webview.form % form_vals)
webview.py
from string import Template
params = dict(op1='%(op1)s',op2='%(op2)s',op3='%(op3)s')
template = Template("""
<label>Temp_Status
<select name='status'>
<option value='o'${op1}>Opened</option>
<option value='c'${op2}>Completed</option>
<option value='a'${op3}>Aged</option>
</select>
</label><br><br>
""")
form = """
<form method='post' action='/tasksystem/taskform'>
...
""" + template.substitute(params) + """
...
</form>
"""

Categories

Resources