I'm diving into Flask for the first time and I'm having some trouble getting something work.
I currently have a template for when my tab values is empty, it contains a form that when submitted should call a specific function using the parameters of the form and return another template. Each call of the form should in, fact call the index.html template with different values.
Relevant parts of code are as follows:
main.py
#app.route('/', methods=['POST','GET'])
def main():
global maxDepth, numberOfRelated
if not values:
return render_template('initial.html')
if request.method=='POST':
url = request.form['url']
maxDepth = request.form['depth']
numberOfRelated = request.form['numberOfRelated']
values = crawling(url,maxDepth,numberOfRelated)
return render_template('index.html',var=values)
The form part of initial.html and index.html are actually the same
<form class="form-inline" action="/" method="POST">
<div class="form-group">
<input name='url' type="text" class="form-control"/>
</div>
<div class="form-group minorForm">
<input name='numberOfRelated' type="text" class="form-control" />
</div>
<div class="form-group minorForm">
<input name='depth' type="text" class="form-control" />
</div>
<div class="form-group navbar-right">
<button class="btn btn-success minorForm generate" type="submit"> Generate</button>
</div>
</form>
In your main method, unless values is global, it won't be defined for if not values.
As to your question, add another render_template call just after the conditional for if the form was submitted:
if request.method=='POST':
url = request.form['url']
maxDepth = request.form['depth']
numberOfRelated = request.form['numberOfRelated']
values = crawling(url,maxDepth,numberOfRelated)
return render_template('index.html',var=values) # 1
return render_template('index.html',var=values) # 2
If the form is submitted, the conditional will be true and the template will be rendered at comment #1. If the user is navigating to the page normally, the conditional will be false and the line with comment #2 will be called.
I'm a bit confused about the question, but you should always redirect after a POST (unless there was an error in the form and no action was taken). That way the same action won't be repeated if the user reloads the page.
Related
As you can see in the picture below I'm trying to have the user search for a given country, start/end date and get the result of "Confirmed Cases" and "Date" back from the API, but I'm not sure how to do it.
I tried using this API, to fill the drop-down menu of the countries -->
https://api.covid19api.com/summary
but this is the other API that I have to use but while changing the parameters for the country and dates -->
https://api.covid19api.com/country/afghanistan/status/confirmed?from=2020-09-06T00:00:00Z&to=2020-09-11T00:00:00Z
Here are snippets of my code:
views.py
def home(request):
# second_response = requests.get('https://api.covid19api.com/country/afghanistan/status/confirmed?from=2020-09-06T00:00:00Z&to=2020-09-11T00:00:00Z').json()
second_response = requests.get('https://api.covid19api.com/summary').json()
my_list = []
for i in range(0, len(second_response['Countries'])):
my_list.append(second_response['Countries'][i]['Country'])
if request.method=='POST':
selected_country = request.POST['selected_country']
print('here', selected_country)
return render(request, 'home.html', {'my_list': my_list})
home.html
<div class="container justify-content-center">
<form action="{% url 'home' %}" method="post">
{% csrf_token %}
<label for="selected_country" style="margin-right: 5px;"> Select a Country, Start & End Dates : </label>
<select name="selected_country" >
{% for object in my_list %}
<option value="">{{object}}</option>
{% endfor %}
</select>
<label for="startdate"></label>
<input type="date" id="startdate">
<label for="enddate"></label>
<input type="date" id="enddate">
<input type="submit" value="Search" />
</form>
</div>
PLUS: when I click on "search" i should get the value of the selected_country because I tried printing it, but it doesn't show for some reason, so the method is post but for some reason I can't get back the selected_country
Any help is appreciated
JAVASCRIPT
if you have any solid grasp of javascript i recommend you do that in javascript, because it will just make it better and easier
otherwise :
view.py
def handler(request):
if request.method=='POST':
selected_country = request.POST['selected_country']
startDate= request.POST['startdate']
endDate= request.POST['enddate']
request_handler = requests.get(f"https://api.covid19api.com/country/{selected_country}/status/confirmed?from={startDate}T00:00:00Z&to={endDate}T00:00:00Z")
if request_handler.status_code=200:
#To prevent errors
request_json=request_handler.json()
else:
pass # do something
return render(request, 'result.html', {"json":request_json})
#you should handle the data at the front end using jinja blocks
note : i don't know much about Django so the code may break
I have a simple page with a data entry field and a click button, this will run the API to retrieve the coin data
running the code in a python terminal return with success, but when I try to add it to flask and use the webpage, I get the error 405 method not allowed for the POST.
This is the main python/flask file:
crypto.py
# template libraries
from flask import render_template,url_for,flash,request,redirect,Blueprint
# Coingecko API library
from pycoingecko import CoinGeckoAPI
crypto_simulator = Blueprint('crypto_simulator',__name__)
#crypto_simulator.route('/crypto_simulator', methods=['GET','POST'])
#login_required
def crypto_insert():
if request.form.get("ident") == "formCrypto":
print('Hello')
cg = CoinGeckoAPI()
#crypto_token = request.form.get('crypto_name_html', '')
crypto_token = 'bitcoin'
crypto_currency = 'usd'
response = cg.get_price(ids=crypto_token,
vs_currencies='usd',
include_market_cap='true',
include_24hr_vol='true',
include_24hr_change='true',
include_last_updated_at='true')
crypto_result = response.get(crypto_token,'')
print(crypto_result[crypto_currency])
return render_template('crypto_simulator.html',
formCryptoSimulation=form,
crypto_token=crypto_token,
crypto_currency=crypto_currency,
crypto_result=crypto_result
)
This is the Blueprint routing file:
core.py
# crypto section
#core.route('/crypto_simulator')
def crypto_simulator():
return render_template('crypto_simulator.html')
This is the Flask/Bootstrap front-end:
crypto_simulator.html
{% extends "base.html" %}
{% block content %}
<!-- Simulation Code Start -->
<div class="forms">
<div class="formCrypto">
<form method="post" action="{{ url_for('core.crypto_simulator') }}">
<div class="container">
<div class="row g-3">
<div class="col-sm-3">
<label class="form-label"><b>Crypto Name:</b></label>
<input type="text" class="form-control" name="crypto_name_html" placeholder="Enter Crypto Name" required>
</div>
</div>
</div>
<br>
<div class="d-grid gap-2 d-md-flex justify-content-md-start">
<button id="btn" type="submit" class="btn btn-info">Check Token!</button>
</div>
<input type=hidden name="ident" value="formCrypto">
</form>
<br>
<p>Token: <b>{{crypto_token}}</b>
<p>Price: <b>{{crypto_result}}</b>
</div>
</div>
{% endblock %}
I checked for misspelled lines and anything related but still stuck into how to fix it...
Your form has this:
<form method="post" action="{{ url_for('core.crypto_simulator') }}">
So you are calling the function crypto_simulator in blueprint core:
#core.route('/crypto_simulator')
def crypto_simulator():
return render_template('crypto_simulator.html')
Note that your form does a POST request, so you very logically have to enable the POST method on the function being called like this:
#core.route('/crypto_simulator', methods=['GET','POST'])
I have a footer that contains a form on every page. I don't want the user to be redirected to a page when submitting the form. Instead, onclick button leads the user to a change in text in the footer on the same page. However, whenever the user inputs his email, and presses "enter" on the keyboard instead of the button, the page is immediately redirected to a "Method Not Allowed
The method is not allowed for the requested URL."
<form action="" method="POST">
<div id="theDiv" class="col-xl-auto col-md-6 col-12 pt-4 my-sm-0 order-6 ">
<div class="form-group"><label for="email" class="mb-3"><b>Subscribe to our Mailing list</b></label><input type="email" name="email" class="form-control form-control-lg" placeholder="Enter email" id="email"></div><button type="button" class="buttonsqred btn btn-primary btn-lg btn-block my-2 Subscribe mt-4 mb-3" onclick="document.getElementById('theDiv').textContent = 'You Successfully Subscribed!'; document.getElementById('theDiv').style.color = 'red'" >Subscribe</button>
</div>
</form>
#app.route('/subscribers', methods=['POST', 'GET'])
def subscribers():
title = "Subscribers"
if request.method == "POST":
subscriber_email = request.form['email']
new_subscriber = Subscribers(email=subscriber_email)
# Push to DB
try:
db.session.add(new_subscriber)
db.session.commit()
return redirect('/subscribers')
except:
return "There was an error adding your Subscription"
else:
return render_template("subscribers.html")
The action attribute on your HTML <form> tag is empty, that is why it does not work.
The action attribute should be /subscribers or {{ url_for('subscribers') }} if you want to use Jinja.
The type attribute of your <button> is button instead of submit, so clicking the button does not send the form.
Examples:
<form action="/subscribers" method="POST"> ... </form>
<!-- Jinja Example -->
<form action="{{ url_for('subscribers') }}" method="POST"> ... </form>
If you want to send the form without redirection, this question is already answered here (pure JavaScript solution): https://stackoverflow.com/a/54964425/11297557
I've created a template for updating account profiles using a Bootstrap snippet (from https://www.bootdey.com). With the django default format (like {{ form.as_p }}), updating accounts works (for example, when I modify the first name, it changes in the database). When I use the bootstrapp snippet, it doesn't update: it goes straight to 'homepage' without updating (as explained in views.py).
In forms.py
class EditAccountForm(UserChangeForm):
class Meta:
model = Account
fields = ('email','first_name','last_name')
In views.py
def EditProfile(request):
context= {}
if request.POST:
form = EditAccountForm(request.POST, instance=request.user)
if form.is_valid():
form.save()
email = form.cleaned_data.get("email")
raw_password = form.cleaned_data.get("password1")
account = authenticate(email=email,password=raw_password)
return redirect('profile_page')
else:
context['edit_form'] = form
return redirect('homepage')
else:
form = EditAccountForm(instance=request.user)
context['edit_form'] = form
return render(request,'Account/edit_page.html',context)
the template: edit_profile.html (I only show the first_name part as example)
<form method = "POST" class="form" novalidate="">
{% csrf_token %}
<div class="row">
<div class="col">
<div class="row">
<div class="col">
<div class="form-group">
<label>First name</label>
<input class="form-control" type="text" name="firstna" value={{ edit_form.first_name.value }}>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col d-flex justify-content-end">
<button class="btn btn-primary" type="submit">Save Changes</button>
PS: I've preferred to use those snippets instead of the Django style since I find them more attractive and offer more freedom.
Please check you are taking same value if you are changing the data in views like if you are using (name="firstna") in template so for First Name you have to take same in views.
Same question is asked here you can go and follow below link
[How to update user profile in Django
First of all sorry if that's a silly question, but I am kind of stuck..
I want to pass a couple of variables from my HTML/Bootstrap page to Flask. The variables are obtained in a form.
The variable is to be selected from a dropdown. Once the variable is selected from mySQL2 it should be stored in customername.
At the moment I've got this sample code which does not work at all.
<form action="" class="form-group" method="post">
<div class="form-group">
<label for="selectcustomer">Select your customer</label>
<input
<select class="form-control" id="selectcustomer">
{% for j in mySQL2 %}
<option>{{j[2]}}</option>
{% endfor %}
</select> value="{{request.form.customername}}">
<input type="text" class="form-control" name="customername" value="{{request.form.customername}}">
</div>
<br>
<input class="btn btn-default" type="submit" value="Submit">
</form>
How can I post the selected value into customername?
The form looks like this:
I need the selection field to be a dropdown. Once a value is selected it should be stored in customername.
Before form submission can't get the submit values. To get posted data in view use:
request.form["selectcustomer"]
note: html select tag should have a name attribute <select name="selectcustomer" ...> so you can get value with name not the select id.
Lets say you have a view as follows:
def customer():
customername = ""
if request.method == 'POST':
customername = request.form["customername"]
return render_template("yourhtmlfile", customername=customername)
#yourhtml
...
{{customername}}