Running Python code from an HTML form - python

I am making a web server using webpy and right now I have a simple form and a special class I wrote. I want the user to be able to write in code to the form and if the input is a function call, to call the function the user submitted, else do anything with the input if it's not a function call. I believe this would have to be achieved somewhere in the template file? any help would be appreciate

If I understand correctly, you're looking for a way to run client-submitted code on the server, getting input from a form.
So assuming you have a form template that looks something like this (note the name of the textarea element):
<form method="POST">
<textarea name="code" />
<input type="submit">
</form>
you will want to add a POST method to your page class to handle the input and run the code:
class MyPage:
def POST(self):
data = web.input()
eval(data.code)
This is not something you should do with a form that is accessible to anybody you don't trust completely, as it gives the ability to run any code they want on your web-server (e.g. they could easily try and delete all the files on the server). But if you're ok with the security risks or just playing around, be sure to read the docs for Pythons eval to see the other arguments you can pass to it.

Create a Python cgi script and run it in cgi-bin of your webserver. Here is a tutorial. Then the script can access the form's input and do whatever you want with it.

Related

Django: how to get HTML input field value to django view?

i want to get a value in an input to a django views, this is not a form as i am not trying to submit any form, i just need the value that is in the input field
this is the html template
<input readonly name="ref_code" type="text" value="{{ request.user.profile.recommended_by.profile.code }}">
this is my django views
code = str(request.GET.get('ref_code'))
print("This is the code:" + code)
It keep printing This is the code: None
NOTE: i have also tried using request.POST.get("ref_code") it did not still work
What might be the issue?
You definitely need something like a form.
So, let's walk you step by step on how your code works.
First, there is a view which prepares the data to be rendered with the template. This view responds to the first request from the user's browser and returns the rendered template as a static html page to the user.
Second, user's browser displays received html page to the user.
Third, user enters something into the input field.
At this stage the data user has entered is still on their side in their browser.
At this point you have two options:
Use a form to let user send the data to some view on the server which will then process the received data.
Use JavaScript to capture the entered data and send it to the server using an AJAX request.
I guess, you would like to use the second option in this case.
I'd recommend to read a guide on AJAX basics. The Ajax guide on MDN is a good place to start.

Is there any way to link existing inputs to django form?

Working on an app, I initially started developing the UI via QT (PySide2) but I paused it to work on a full "online version" via Django.
The fact is that I'm learning/discovering the framework and how it works step after step.
For all HTML I'm building those on Bootstrap Studio which help me to save A LOT of time and of course make things totally easier for me.
My current problem is that I just discovered how not simply inputs/forms work in Django (My own opinion !). My app works with several bootstrap modals in order to Add/Edit "element" which are the kind of instances of my app and which will be write/read/edit in the database.
The problem here is I already created all HTML pages and related bootstrap-modals and I can't find any way on the internet to link my existing bootstrap-modals to Django forms.
As far as I understood Django forms "caricaturaly" works like this: Django generates a form that you have to dynamically integrate into your HTML.
The fact is it doesn't really arrange me because :
I already have my bootstrap-modals with their inputs looking how I want
I don't really want a bad looking forms as Django generates
I have other elements in the form which are not related to a form (progress bar)
Any other things I have no idea about since I am a beginner in Web!
Therefore, my main question here would be: Is there any simple/accessible way to get the inputs as it would be via QT, by this I mean :
Opening the modal
Filling Input_1, Input_2, Input_3
Any way in Django files to get those inputs and then saves those in DB (one by one)
My apologies if really looks dumb here but I am really new to Django/Web, I know CSS/HTML syntax, I have NO knowledge in JavaScript and I would say that my Python level is Intermediate (enough for all my back-end uses).
Thank you in advance for your help!
A simple example of using a form for validation/processing but not html generation.
Assume we have this existing form
<form action="/some-url" method="POST">
<input id="foo" name="foo" type="text"/>
<input id="bar" name="bar" type="text"/>
<input id="baz" name="baz" type="text"/>
</form>
you can represent it with this Django form:
class MyForm(forms.Form):
# Field names should match the 'name' attributes in the html inputs
foo = forms.CharField()
bar = forms.CharField()
baz = forms.CharField()
And use it in view like this
def my_view(request):
if request.method == 'POST':
form = MyForm(request.POST)
if form.is_valid():
# Do stuff
return HttpRedirectResponse('/success')
# No need to pass the a form to the template, because we aren't
# using it to generate html.
return render(request, 'view.html', {})
If you want to use a field from the html form separately, without using a Django form at all, access it directly:
some_val = request.POST['some_val']
(beware of false booleans and disabled fields, which will not be present in request.POST).

Variable URLs and passing non-input value from html to Python (Flask)

According to this question you can only send data from input forms from html to Python with POST. I'm trying to figure out how to pass a value (that's actually originally contained in a dictionary that I passed in from Python) from html to Python.
My two approaches I considered (and have not figured out how to do successfully) are:
Taking a look at the Flask quickstart, this should be quite simple. I'm just not sure what the syntax should look like on the html side to pass in this parkCode.
#app.route('/park/<parkCode>', methods =['GET', 'POST'])
def park(parkCode):
return render_template('park.html', parkCode = parkCode)
Alternatively, is there some way to simply send a string from html to Python without using an input form? I have yet to find a way to do this.
For reference, this is the line where I'm sending over the ```parks`` dictionary:
return render_template('search_results.html', parks=parks)
Then, in my search_results.html file:
{% for park in parks %}
<div method = "POST" action = "/park">{{park["fullName"]}}</div>
{% endfor %}
But I want the to send the park["fullName"] to my Python code.
.route decorator always handles only URL paths. Since form action is a static value in HTML, the only way to change it is to use JavaScript (for example, by changing the action attribute at submit time). If you're going to use JavaScript, you might as well then just use JavaScript to submit the request itself, which leads us to
Yes, you can use AJAX to send a request. Since ES6, the easiest way to do this is fetch. The choice of whether to use a form or whether to use AJAX depends on what you want to happen after the request: a submitted form results in a new page being rendered, while an AJAX request cannot change the current page, only trigger JavaScript code (although obviously you can change the page in JavaScript should you so wish).
Basically, you can't do what you want without JavaScript. The third option that does work without JavaScript is using the form as it was meant to be used. On flask side, it involves not naming the parameter inside the route, but using request.args (for GET forms) or request.form (for POST forms):
#app.route('/park', methods =['POST'])
def park():
parkCode = request.form.get('parkCode')
return render_template('park.html', parkCode = parkCode)
with the accompanying HTML:
<form action="/park" method="POST">
<input name="parkCode"/>
<input type="submit" value="Submit"/>
</form>

Remove URL Params after page loads in Google App Engine

First of all, I am very new to web programming in general. I've read lots of tutorials online and it's a little confusing since some of them are out-dated. So if I'm heading down a path that is fundamentally wrong, I'd love suggestions about The Right Way. Having said that, this is just a for-fun project, so if there is a simple (<10 lines) way to get what I want, I'd love to see quick results today even if long-term I end up fundamentally changing things.
So anyway, I'm using Google App Engine (Python 2.7) to do a simple calculation. I show a form, the user fills in values, clicks a button at the bottom, and some result text is displayed with the result of the calculation. This part is working fine.
For my own testing, it's annoying to always re-type the input values, and some of the fields aren't totally obvious to users, so I'd like to be able to send a link to someone off the form "http://buggyapp.appspot.com/calculation?input1=100&input2=200" and have it fill in those two parameters. This part works, too.
The problem is when the user loads that sort of link, changes one of the values in the form, and then clicks the button. Instead of using the (changed) form value, it uses the value in the URL. I'd like to fix that, and ideally I'd like the URL bar to not even show the URL Params after the page loads.
I'm not sure what info is necessary to help you find what I'm doing wrong.
Here's a section from the HTML, which is a Jinja2 template:
<form method="post">
<input value="{{ input1 }}" name="input1">
<input value="{{ input2 }}" name="input2">
<button class="submit" type="submit">Calculate</button>
</form>
<p>{{ result }}</p>
Here's the python code:
def get(self):
input1 = request.get('input1')
input2 = request.get('input2')
# some irrelevant(?) code to set default values on the initial load if there are no URL Params
result = str(input1+input2) #actual calculation slightly more complicated than this
template = JINJA_ENVIRONMENT.get_template('calculation.html')
self.response.write(template.render(vars()))
It seems to behave the same no matter whether I put the calculation in the get handler or post handler. At the moment, I'm simply calling one from the other:
def post(self):
input1 = request.get('input1')
print input1 # even this shows the URL value (if one exists), not form value
return self.get();
So, my next step to make it work would be to change the names of the form inputs so they are different from the URL Params, and add extra code to merge the potential input sources. But that won't really get me what I want, which is for the URL Params to disappear once they have populated the input forms. It also complicates the part of the code that generates those sorts of links.
I'd prefer a Python-only solution, but I'm open to using javascript. There are other stack overflow questions/answers that imply a javascript mechanism will do what I want, but I don't understand any of them well enough to apply them to my problem.
I'm sure I'm doing lots of other things wrong, and I may have over-simplified things or not posted enough info. I'm here to learn, so fire away. And thanks in advance for the help.
tl;dr- How do I use the URL Params once and then remove them from the URL so they don't override form inputs on subsequent posts?
HTTP GET requests usually include the parameters in the URL since there's no other place to pass them (there's no request body).
HTTP POST requests usually include the parameters in the request body, though it's still possible to include the parameters in the URL.
It looks like you're using some sort of Javascript to post the form. Make sure you are using a POST request and putting the parameters in the POST body. Most libraries automatically put params in the POST body as long as you're issuing a POST request.
EDIT:
Forms usually issue POST requests by default. Usually the <form> element will have an action attribute that specifies the URL to send to. However, if it doesn't have an action attribute it'll issue a POST request to the current URL.
In your case the current URL contains parameters and those are submitted again with your request. You should have a few options.
Specify the action in your form so you aren't submitting to the same url with parameters already attached.
In your request handler, read the data out of the post body (request.POST['input1']) instead of the url.

Getting the name of a checkbox submitted by GET

So I'm trying to use the CGI module that comes with Python, on a Python Server Page.
I want to know if there is any way to pull the name of the checkbox, when it is submitted. I don't actually need to know the status of whether it is on or off (because off won't submit to the new page), just what the name is, because that's how the script is going to run.
I.e., on my first page I have
<input type="checkbox" name="AV-D01">
I submit this form, and it has the form of
formchangedate.psp?AV-D01=on
All I care to pull from this is the AV-D01 - is there anyway to do so?
cgi.FieldStorage() returns a dictionary containing the parameters of the request.

Categories