Keeping checkbox values with gae-sessions - python

I look for answers but It was all about php. I got this index.html:
<form method="post">
<input type="checkbox" name="opts" value="opt1" opt[0]> option 1<br>
<input type="checkbox" name="opts" value="opt2" opt[1]> option 2<br>
<input type="checkbox" name="opts" value="opt3" opt[2]> option 3<br>
<br>
<input name="" type="submit" value="Save" >
</form>
and this main.py
import webapp2
import cgi
import os
import jinja2
from gaesessions import get_current_session
class MainHandler(webapp2.RequestHandler):
def get(self):
session=get_current_session()
opt=session.get('opt',[]) jinja_environment=jinja2.Environment(autoescape=True,loader=jinja2.FileSystemLoader(os.path.join(os.path.dirname(__file__),'templates')))
tpi_vars={"opt":opt}
template=jinja_environment.get_template('index.html')
self.response.write(template.render(tpi_vars))
def post(self):
opt=self.request.get("opt", allow_multiple=True)
session=get_current_session()
session['opt']=opt
I want to store checked checkboxes and get them. How can I make this possible?

Your Python code seems correct, apart from one weird bug whereby the line using jinja_environment is concatenated to the previous one (?!).
Your Jinja template seems wrong as it doesn't look in the environment, nor does it mark any checkbox as checked. I would recommend something like:
<input type="checkbox" name="opts" value="opt1" {{ops.get('opt1','')}>
option 1<br>
and so on -- the double braces to check into the environment, and a dictionary ops that you could prepare on the Python side.
Right now what you get as opt is a list such as e.g ['opt1'] if that's the only checked checkbox at post time. You could deal with that in the Jinja side, but it's easier on the Python side, I think. So, instead of:
tpi_vars={"opt":opt}
I'd do:
tpi_vars={'ops': dict.fromkeys(opt, 'checked')}
Of course, you don't have to do it just before you render the Jinja2 template -- you could do this list-to-dict translation at any time. But since it is about presentation issues, this seems a good place for it.

Related

HTML, how to auto select the date time picker from sql database

I've a HTML form for editing existing data.
Let's say today is 10/06/2022 18:05 and i want to edit my course date time in my web app.
My course date on the data base is 21/08/2023 10:00. I want to change it to 22/08/2023 10:00. When I open my from on the web app all the inputs came with the existing data already selected. But date time picker comes as 10/06/2022 18:05. I've set the value as the date attribute of course object but it's not working. This works for the rest of the inputs but not for the datetime input.
I basically need the html date time picker comes with autoselected with the existing saved data <course.date> .
I'm writing this web app on python flask and using a postgresql for database. The other inputs comes with selected values but not datetime input.
Anyone has any ideas how to approach this one?
<form action="/courses/{{course.id}}" method="post">
<label for="course">Course Title</label>
<input type="text" name="title" value="{{course.title}}">
<label for="date">Date</label>
<input type="datetime-local" name="date" value="{{course.date}}">
<label for="capacity">Capacity</label>
<input type="number" name="capacity" value="{{course.capacity}}">
<label for="active">Active</label>
<select name="active">
<option value="True">Active</option>
<option value="False" {% if course.active == False %} selected {%endif%}>Deactive</option>
</select>
<input type='submit' value="Update Course">
</form>
If I am understanding the issue right:
course_date in the database is: 21/08/2023 10:00
course_date in the app remains as the local-current time: 10/06/2022 18:05 (example)
GET request properly loads data from the database into the other fields except course-date
you've tried making a POST request to update course_date, but the field doesn't change
My suggestion to debug this is to look at the responses to your GET request. What do they come out as?
Inside your GET request's response,
if the course-date is 21/08/2023 10:00, that means your problem is in your javascript or the code that plugs in your field value inside the HTML. Your frontend field is simply ignoring the response from flask or the data is not being mapped/handled right
if the course-date is 10/06/2022 18:05 or is null. That means your flask backend is broken, double-check the flow of your data from the SQL select -> storing the data in a python variable -> sending the data out
Also remember to Hard-Reload.
Based on our exchange in comments, it looks like the issue is with the date format being passed in your template.
Changing:
<label for="date">Date</label>
<input type="datetime-local" name="date" value="{{course.date}}">
To:
<label for="date">Date</label>
<input type="datetime-local" name="date" value="{{course.date.isoformat()}}">
Should correct the problem for you.

Flask form data empty [duplicate]

This question already has answers here:
Sending data from HTML form to a Python script in Flask
(2 answers)
Closed 1 year ago.
I've created a form with flask. This is the python code that handles the requests that come from this form:
#app.route("/submitclips/", methods=['GET', 'POST'])
def submitclips():
print(request)
print(request.method)
result = request.form.to_dict(flat=False)
print(result)
print(request.data)
HTML code:
<form action="/submitclips" method="POST">
<input type="hidden" name="taskpath" value="paththotask">
<table>
<th>Video</th>
<th>Mute</th>
<th>Delete</th>
<th>Keep</th>
<tr>
<td>
<video width="320" height="240" controls>
<source src="videosource.mp4" type="video/mp4">
</video>
</td>
<td>
<input type="radio" id="name$mute" name="name" value="mute">
</td>
<td>
<input type="radio" id="name$delete" name="name" value="delete">
</td>
<td>
<input type="radio" id="name$keep" name="name" value="keep" checked>
</td>
</tr>
</table>
<input type="submit">
</form>
This is a table and has more than one row, I changed the values to make it more readable. I guarantee that all names are unique where they are supposed to be unique though.
It has some code below it, but it crashes there because the form seems to be empty. I have checked the HTML and it's all correct, all inputs have a name. I also recorded the network traffic on google chrome to test this and I can see that all data in the form is present in the request data. So I'm pretty sure it's correct on the front-end. The problem is that it just doesn't show up in this method. In the code you can see several print statements and all of these show me empty data and not the data that I could see in my chrome browser. The method is GET, I don't know if it should be GET. In HTML I selected it to be a POST method, but if I remove the GET option from the python code, it gives me a "method not allowed" error.
I don't know what to do, this is some older code that used to work on my windows machine. I didn't change anything about it, but now I'm working on linux and it's completely broken, none of the forms work, it's all empty data.
Here you have mentioned that the endpoint /submitclips has methods GET and POST. It means that whenever i hit the url "baseurl/submitclips" then this function will be executed. Inside the function you have not specified for which method you will have what response, i.e if i call the endpoint using GET or POST you will process it the same way. This is not a good practice. I suggest you put something like :
if request.method == 'POST' or if request.method == 'GET' to separate the execution based on the type of method.
Now coming to the HTML, you must have the HTML from where you are sending the request to the server. If that data is coming from a form, then as part of the form you can add two attributes,
<form method="post"> and <form action="/submitclips"> to specify that on submit of this form,you will be sending the form data through POST method to the "/submitclips" url. It will look like this.
<form method="post" action="/submitclips"">
For the Server side,
def submitclips():
if request.method == 'POST' :
print(request)
print(request.method)
result = request.form.to_dict(flat=False)
print(result)
print(request.data)
It should work after that.
I have found the error. My HTML code would submit the form to "/submitclips" while the python code received requests from "/submitclips/". I don't know why this is wrong though, the tutorial that I followed for flask told me specifically that putting a slash at the end meant that it could receive requests from both "/submitclips" and "/submitclips/". This also worked earlier on my windows machine, but doesn't work anymore on my linux machine. I'm glad it's solved, but if anyone has an explanation for why this is wrong, feel free to answer.

Flask - getting a value from a Vue MultiSelect Element

I have a Vue-multiselect, as in this example (not mine)
https://jsfiddle.net/gmsa/04jvjuv3/
I'm trying to get the value in the multi select element and POST it back to my Flask app.
HTML
<form action="" method="POST">
<multiselect id="multi", name = "multi" :multiple="true" :hide-selected="true" :selected="selected" :options="options" :taggable="false" #update="updateSelected"></multiselect>
<button type="submit" value="l1" >Load</button>
</form>
Flask
if request.method == 'POST':
print request.form.getlist('multi')
#prints an empty list
print request.form['multi']
#hits a bad request error
I've been klutzing about with this for a long time now - why can't I get the value from the form element?
The thing is that vue-multiselect is meant to be handled using pure javascript. So, you could just use the solution implemented by the user in that issue.
In HTML:
<input style="display: none;" :value="selected" name="multiselect">
Inside the form, and in python:
request.form.get('multiselect').split(',')
The split is in case multiple options were selected.
BTW, that fiddle uses old versions of both vue and multiselect, but that's unrelated.

Create a script which will automatically input data into a HTML Text field

Suppose there is a simple form.html file containing the following code :
<form>
First name:<br>
<input type="text" name="firstname" value="">
<br>
<input type="submit" value="Submit">
</form>
I want to create a python script which should automatically fill the value in the text field and submit the form. How do I do?
While this is opinion based, there are several Python (and command line) tools you could use. Read up on a few packages:
Python requests http://docs.python-requests.org/en/master/
Selenium http://www.seleniumhq.org/
curl https://curl.haxx.se/docs/manpage.html
Good luck.

Using Urllib instead of action in post form

I need to allow users to upload content directly to Amazon S3. This form works:
<form action="https://me.s3.amazonaws.com/" method="post" enctype='multipart/form-data' class="upload-form">{% csrf_token %}
<input type="hidden" name="key" value="videos/test.jpg">
<input type="hidden" name="AWSAccessKeyId" value="<access_key>">
<input type="hidden" name="acl" value="public-read">
<input type="hidden" name="policy" value="{{policy}}">
<input type="hidden" name="signature" value="{{signature}}">
<input type="hidden" name="Content-Type" value="image/jpeg">
<input type="submit" value="Upload" name="upload">
</form>
And in the function, I define policy and signature. However, I need to pass two variables to the form -- Content-Type and Key, which will only be known when the user presses the upload button. Thus, I need to pass these two variables to the template after the POST request but before the re-direction to Amazon.
It was suggested that I use urllib to do this. I have tried doing so the following way, but I keep getting an inscrutable HTTPError. This is what I currently have:
if request.method == 'POST':
# define the variables
urllib2.urlopen("https://me.amazonaws.com/",
urllib.urlencode([('key','videos/test3.jpg'),
('AWSAccessKeyId','<access_key'),
('acl','public-read'),
('policy',policy),
('signature',signature),
('Content-Type',content_type),
('file',file)]))
I have also tried hardcoding all the values instead of using variables but still get the same error. What am I doing incorrectly and what do I need to change to be able to redirect the form to Amazon, so the content can be uploaded directly to Amazon?
I recommend watching the form do its work with Firebug, enabled and set to the Net tab.
After completing the POST, click its [+] icon to expand, study the Headers, POST, Response tabs to see what you are missing and/or doing wrong.
Next separate this script from Django and put into a standalone file. Add one thing at a time to it and retest until it works. The lines below should increase visibility into your script.
import httplib
httplib.HTTPConnection.debuglevel = 1
I tried poking around with urllib myself, but as I don't have an account on AWS I didn't get farther than getting a 400 Bad Request response. Seems like a good sign, probably I just need valid host and key params etc.

Categories