Django: Call Python Function on Button Click and Display String - javascript

I found a couple of resources online, but none that worked for me. Here is what I currently have:
In views.py:
def button(request):
return render(request, 'home.html')
def display_text(request):
return HttpResponse('TESTING', status=200)
In urls.py:
urlpatterns = [
url(r'^$', views.button),
url(r'^display_text', views.display_text, name='script'),
]
In home.html:
<div class="row">
<input type="text" class="form-control js-text" id="input-box" placeholder="Type something to begin..."/>
<div class="col-md-12" style="text-align:center;">
<button onclick="location.href='{% url 'script' %}'"></button> <hr>
</div>
</div>
What happens right now is that it displays the string on a new web page. What I want to do is populate my text-box with that string returned by my Python function, and display it on the current page. How can I do so? Thanks!

The easiest way to do this is to make use of the render function provided by Django. This function combines a context and a template and renders a HttpResponse. You can change the display_text function to the following:
def display_text(request):
return render(request, 'home.html', {'string': 'TESTING'})
#Im assuming home.html is the the page you want to render
Now you can make use of Django templates to show the data sent through the context like so:
<div>
<p>{{string}}</p>
</div>

Related

How to get value from HTML user input in django view?

Hello everyone I have an HTML form as follows:
and after clicking on post i am redirecting it to views.py. can any one tell me how to get the field values of all the fields of the form into views.py.
here's the output
i want the field value in key value pair like shown in above pic i.e. API=hello&Area=hello1 so on...
i know we can do that using this
if html:
<div class="form-group col-md-2">
<label for="param">TAF Parameter</label>
<input type="text" name="inputdata_API" class="form-control" id="inputapi_param" value="API" readonly>
</div>
and view:
def register(request):
api = request.GET.get['inputdata_API']
But in that case i have to write each and every input name in my view
To get form input without individual access, Django provide ModelForm
For resume :
Define a model to store your form informations
class MyModel(models.Model):
api = models.CharField()
# ...
Define a model form linked to the previous model
from django import forms
class MyModelForm(forms.Form):
class Meta:
model = MyModel
fields = ['api', # all others fields you want to display]
In the views.py
from django.http import JsonResponse
from django.shortcuts import redirect
def register(request):
if request.method == 'POST':
# Instanciate the form with posted data
form = MyModelFor(request.POST)
# Check if form is valid
if form.is_valid:
# Create a new MyModel object if the form is valid
form.save() # This is the most benefit line, save you from request.POST['field_name']
# You can eventually return to the same page
return redirect('.')
else: # The form is invalid return a json response
return JsonResponse({"Error": "Form is invalid"}, status=400)
At the end render the form fields in the template like this :
<form action="{% url 'url_to_register' %}" method="post" novalidate>
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn btn-success">Register</button>
</form>
But the downside of this approach is the style of the form on the frontend :
You need to add some Bootstrap class for example in the right place to make it nice to look, it is a a counterpart...
Django form documentation.

How can I show a div or html element after submitting a form and retrieve some information from a view in Django

Currently when the user introduces a string in an input field and clicks the submit button, this invokes a view that returns through return render(request, 'index.html', context) a context that
it basically contains data that is displayed in a table.
I would like said table to be visible only after submitting the form and not before and that when it is visible it shows the information obtained from the view.
The problem is that if through inline styling I make this table not visible, for example in the following way:
<div class="row" id="searchVariantTable" style="display: none;">
<!-- SOME TABLE HERE-->
</div>
And then I use the onsubmit event for form or onclick for button, it doesn't work. (It works partially, I can see the tbody but thead is missing, so basically I can't display the retrieved data from the database).
Similarly, if I try something like this:
$('document').ready(function() {
$('#searchVariantTable').hide();
$('form').submit(function(e) {
$('#searchVariantTable').show();
e.preventDefault();
});
});
It doesn't work either.
I think the last option, if I'm not mistaken, is AJAX, but I'm not quite sure how to do something like that with Django (it's my first time using Django)
What am I doing wrong? Is there an option that I am missing?
You can try by using if else in django template:
index.html
<form method="post">
<input type="submit">
</form>
{% if allowed == "yes" %}
<!-- your table code -->
{% endif %}
and in views.py
if request.method == "POST":
return render(request, 'index.html',{'allowed':'yes'})
else:
return render(request,'index.html',{'allowed':'no'})

How to redirect to a second page if I visit the application second time

I am trying to create a flask web application where if the user visits my application for the first time, he will be directed to an index.html page, where he will be prompted to enter a name and submit it. Then I save the name in local storage and redirect the user to a second html page channels.html. Now if the user closes the tab and visits the application for a second time, he should be redirected to the second page channels.html, i.e., the "/chanels" route automatically instead of the first page.
Here is the app.py python file I have written so far:
#app.route("/")
def index():
return render_template("index.html")
#app.route("/channels", methods=['GET', 'POST'])
def channels():
if request.method == "POST":
name = request.form.get("display_name")
return render_template("channels.html", name=name)
render_template("channels.html")
Here is my index.html:
<script src="{{url_for('static', filename='index.js')}}"></script>
<h2>Enter your name!</h2>
<form action="/channels" method='Post'>
<input id="displayname" name="display_name" placeholder="Name" autocomplete="off" autofocus required type="text"/>
<input type="submit" id="submitbutton" onclick="store()"/>
</form>
And index.js:
function store(){
var name= document.getElementById("displayname");
localStorage.setItem("displayname", name.value);
}
I tried googling how to do it, but couldn't find a solution.
Any help would be kindly appreciated.
EDIT: On suggestions of #AkibRhast, I tried checking whether localStorage is there or not, and if yes, redirect to channels.html, so I added the following code to my index.js file:
if(localStorage.getItem("displayname")){
window.location.replace("/channels");
}
But now whenever I visit the index page, I get a 404 Not Found error, although the url in the url bar has the link to channels, i.e. http://127.0.0.1:5000/channels.html.
So it seems you are headed in the right direction.
Try this:
In your index.html, add a script at the header of the page/top of the page. You want the script to be loaded 1st
So when a user goes to index.html the script checks whether local storage.getItem("displayName") exists.
If it does, redirect to channels.html
Once you have tried that, and made the appropriate changes to your code, and if it did not work please edit your original post with the things you have now tried, as well as stack trace of any errors.
I am more than happy to take a look at it again and rework my answer.
Updates
So I believe the reason it is not working on your side currently has to do with the fact that in your channels function you need to have a return value for your second render template, like so :
#app.route("/channels", methods=['GET', 'POST'])
def channels():
if request.method == "POST":
name = request.form.get("display_name")
return render_template("channels.html", name=name)
return render_template("channels.html") # This line has been modified
Another change that you need to make in your code for the changes to take effect is to your index.js file. Just add this function.
//This function needs to be added to index.js
window.onload = function(){
if(localStorage.getItem("displayname")){
window.location.replace("/channels");
}
I have implemented the above changes on my end and it seems to work as expected please let me if that works out for you. Also, on a different note, the best way to test this if it is working is using incognito mode.

How to execute file.py on HTML button press using Django?

My goal is to click an HTML button on my Django web page and this will execute a local python script.
I am creating a local web application as an interface to a project. This will not be hosted and will always just run on my local machine. My project is run with a python script (which carries out numerous tests specific to my project). All I need is for a button in my web interface to execute this script on my machine.
I have a template index.html where the whole web page is located. I presume I need to call some form of views function possibly when the button is pressed?
How to execute python code by django html button?
This question suggests:
def index(request):
if request.method == 'GET':
return render(request, 'yourapp/index.html', {'output': ''})
elif request.method == 'POST':
py_obj = mycode.test_code(10)
return render(request, 'yourapp/output.html', {'output': py_obj.a})
I tried this just as a test but nothing happened when I went to the URL (located in the appropriate views.py):
def runtest(request):
print("Hello World")
Popen(['gnome-terminal', '-e', 'echo "Hello World"'], stdout=PIPE)
return
However I don't quite understand if this achieves what I need it to, I am struggling to understand what the answer is suggesting.
Where in the Django framework can I specify a call to a local python script when a button is pressed?
(I have very limited experience with web applications, this is simply just meant to be a simple interface with some buttons to run tests)
You want to try to submit a form on the button click. You can then import the functions you want to run from the script and call them in your view. You then redirect to the same page.
I hope this helps!
index.html
<form method="post">
{% csrf_token %}
<button type="submit" name="run_script">Run script</button>
</form>
views.py
if request.method == 'POST' and 'run_script' in request.POST:
# import function to run
from path_to_script import function_to_run
# call function
function_to_run()
# return user to required page
return HttpResponseRedirect(reverse(app_name:view_name))
Adding to answer above. You can run the function in a different view completely:
<form method="post" action="{% url 'app:view/function' %}">
{% csrf_token %}
<button class="btn btn-danger btn-block btn-round">Perform task</button>
</form>
And render whatever template you want (same template will execute task but seem like nothing has happened). This is handy if you already have a 'POST' form handler.

Return multiple templates

I am currently trying open multiple pages on a POST request. Basically, what I am doing is searching for a job number in the database by sending a POST request and then (trying) opening the multiple pages that correspond with that job number (ex.: a webpage for job location, one for material, etc.) However, I can only return one template for the browser to open. I have looked at many, many questions like this one:
Render multiple templates at once in Flask
However, I am not finding the answer to my question (most likely because I am asking the wrong question...)
Anyway, my code so far is something like this:
HTML:
<form action="/testing" method="POST" id="existBidFormOne" name="existBidFormOne" autocomplete="off">
<!-- Row one holds Title-->
<div class="center row" style="width: 100%;">
<h1>Enter a Job Number or a Project Name:</h1>
</div>
<!-- Row two holds job number-->
<div class="row">
<!-- Column one holds Job number-->
<div class="col-m-6">
<div class="row centerInput">
<div class="col-m-4 inputPad"><b>Job Number:</b></div>
<div class="col-m-8 noPad">
<input type="text" id="exb_jobNumber" name="exb_jobNumber" class="input maxWidth" />
</div>
</div>
</div>
</div>
<div class="centerInput row">
<span>
<button type="submit" id="exb_searchOne" class="srchBtn">Search</button>
</span>
</div>
</form>
FLASK:
#app.route('/testing', methods=["GET", "POST"])
def testing():
if request.method == 'POST':
job_num = request.form.getlist('exb_jobNumber')
if job_num:
session = Session()
results = ds.get_job_info(session, job_num) # returns dict
results2 = ds.get_job_material(session, job_num) #returns dict
session.close()
# open page one
return render_template('pageOne.html', **results)
The above code works well opening one page, however I would also like to open:
render_template('pageTwo.html', **results2)
Thank you!
opening the multiple pages If you want to open multiple pages on a single webpage (i.e. in a single browser tab), then you can combine and render as many separate templates as you want with template inheritance. You can have single base page and nest many sub-pages with any content you want.
If you want to open multiple pages in multiple browser tabs, then you should return only a single main HTML page (i.e. single template), but set variable in that webpage with links of all pages you want to open in new browser tabs. Then, with the help of JavaScript and browser API method window.open() you can open those pages.

Categories