I tried all posiible ways and read many posts in SO. I haven't got any solution for my "method not allowed" error. Can anyone check and let me know what did I do wrong? I am getting frustrated cause I am new to flask and I cannot proceed further.
This is my template file add_cars.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Datastore and Firebase Auth Example</title>
<script src="https://www.gstatic.com/firebasejs/ui/4.4.0/firebase-ui-auth.js"></script>
<link type="text/css" rel="stylesheet" href="https://www.gstatic.com/firebasejs/ui/4.4.0/firebase-ui-auth.css" />
<script src="{{ url_for('static', filename='script.js') }}"></script>
<link type="text/css" rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
<link type="text/css" rel="stylesheet" href="{{ url_for('static', filename='navstyle.css') }}">
</head>
<body>
<div >
<a href="{{ url_for('root') }}">Home</a>
<a href="{{ url_for('list_ev') }}">EV List</a>
<a href="#contact">Contact</a>
<a href="#about">About</a>
</div>
<h2>Add car details</h2>
<div id="firebase-auth-container"></div>
{% if user_data %}
<p align="right">Email: {{ user_data['email'] }}</p>
<button id="sign-out" hidden="true" style="float: right;">Sign out</button>
<div id="login-info" hidden="true">
<form action="/add_cars" method="post">
Car name:<input type="text" value="" name="name_update"/><br/>
Manufacturer:<input type="text" value="" name="manufacturer_update"/><br/>
Year:<input type="number" value="" name="year_update"/><br/>
Battery size:<input type="number" value="0.0" name="battery_update" step="any"/><br/>
Range:<input type="number" value="" name="range_update"/><br/>
Cost:<input type="number" value="" name="cost_update"/><br/>
Power:<input type="number" value="" name="power_update" step="any"/><br/><br>
<input type="submit" value="Add details" name="submit_button"/>
</form>
{% elif error_message %}
<p>Error Message: {{ error_message }}</p>
{% endif %}
</div>
<br>
<!-- <div>-->
<!-- <a href="{{ url_for('list_ev') }}" >View all cars</a>-->
<!-- </div>-->
<script src="https://www.gstatic.com/firebasejs/7.14.5/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.8.0/firebase-auth.js"></script>
<script src="{{ url_for('static', filename='app-setup.js') }}"></script>
</body>
</html>
This is my main.py
from flask import Flask, render_template, request, redirect, url_for
import google.oauth2.id_token
from google.auth.transport import requests
from google.cloud import datastore
import os, random
os.environ["GOOGLE_APPLICATION_CREDENTIALS"]="google_auth_json.json"
firebase_req_adapter=requests.Request()
app = Flask(__name__)
datastore_client = datastore.Client()
def store_time(email):
entity = datastore.Entity(key = datastore_client.key('User', email, 'visit'))
entity.update({'email' : email})
datastore_client.put(entity)
def retrieveCarInfo(claims):
entity_key = datastore_client.key('CarInfo', claims['email'])
entity = datastore_client.get(entity_key)
return entity
def createCarInfo(claims):
entity_key = datastore_client.key('CarInfo', claims['email'])
entity = datastore.Entity(key = entity_key)
entity.update({
'email': claims['email'],
'name': claims['name'],
'cars_list': []
})
datastore_client.put(entity)
def retrieveCars(car_info):
car_ids = car_info['cars_list']
car_keys = []
for i in range(len(car_ids)):
car_keys.append(datastore_client.key('car', car_ids[i]))
cars_list = datastore_client.get_multi(car_keys)
return cars_list
def createCarDetails(claims, new_car_string, new_man_string, new_yr_int, new_bt_float, new_rg_int, new_cost_int, new_pr_int):
id = random.getrandbits(63)
entity_key = datastore_client.key('car', id)
entity = datastore.Entity(key = entity_key)
entity.update({
'name': new_car_string,
'manufacturer': new_man_string,
'year': new_yr_int,
'battery_size': new_bt_float,
'range': new_rg_int,
'cost': new_cost_int,
'power': new_pr_int,
})
datastore_client.put(entity)
return id
def addcarToUser(car_info, id):
car_keys = car_info['cars_list']
car_keys.append(id)
car_info.update({
'cars_list': car_keys
})
datastore_client.put(car_info)
def deleteCars(claims, id):
car_info = retrieveCarInfo(claims)
car_list_keys = car_info['cars_list']
car_key = datastore_client.key('Car', car_list_keys[id])
datastore_client.delete(car_key)
del car_list_keys[id]
car_info.update({
'car_info' : car_list_keys
})
datastore_client.put(car_info)
# All functions below to render data to templates
@app.route("/")
def root():
id_token = request.cookies.get("token")
error_message = None
claims = None
car_info = None
cars = None
if id_token:
try:
claims = google.oauth2.id_token.verify_firebase_token(id_token,
firebase_req_adapter)
store_time(claims['email'])
car_info = retrieveCarInfo(claims)
if car_info == None:
createCarInfo(claims)
car_info = retrieveCarInfo(claims)
cars = retrieveCars(car_info)
except ValueError as exc:
error_message = str(exc)
return render_template('index.html', user_data=claims, error_message=error_message,
car_info=car_info, cars=cars)
# return render_template('index.html', user_data=claims, error_message=error_message)
@app.route("/add_cars", methods=['POST'])
def add_ev():
# add ev's
id_token = request.cookies.get("token")
error_message = None
claims = None
car_info = None
if id_token and request.method=='POST':
try:
claims = google.oauth2.id_token.verify_firebase_token(id_token, firebase_req_adapter)
car_info = retrieveCarInfo(claims)
id = createCarDetails(claims,
request.form['name_update'],
request.form['manufacturer_update'],
request.form['year_update'],
request.form['battery_update'],
request.form['range_update'],
request.form['cost_update'],
request.form['power_update'])
addcarToUser(car_info, id)
except ValueError as exc:
error_message = str(exc)
return redirect(url_for("add_ev"))
# return render_template('add-cars.html', user_data=claims, error_message=error_message, car_info=car_info)
@app.route("/list")
def list_ev():
# listing all ev's
id_token = request.cookies.get("token")
error_message = None
claims = None
car_info = None
if id_token:
try:
claims = google.oauth2.id_token.verify_firebase_token(id_token,
firebase_req_adapter)
car_info = retrieveCarInfo(claims)
if car_info == None:
createCarInfo(claims)
car_info = retrieveCarInfo(claims)
except ValueError as exc:
error_message = str(exc)
return render_template('list_ev.html', user_data=claims, error_message=error_message, car_info=car_info)
@app.route('/delete_cars/<int:id>', methods=['POST'])
def deleteCarFromUser(id):
id_token = request.cookies.get("token")
error_message = None
if id_token:
try:
claims = google.oauth2.id_token.verify_firebase_token(id_token, firebase_req_adapter)
deleteCars(claims, id)
except ValueError as exc:
error_message = str(exc)
return redirect('/')
if __name__=='__main__':
app.run(host='127.0.0.1', port=8082, debug=True)
CodePudding user response:
Could you try adding GET
as a supported method to the below endpoint?
@app.route("/add_cars", methods=['GET', 'POST'])
def add_ev():
# add ev's
...
CodePudding user response:
You need to add support for GET
inside your add_ev
and limit redirect to POST only (otherwise you will end with endless loop) i.e. something akin to
@app.route("/add_cars", methods=['GET','POST'])
def add_ev():
...
if request.method == 'POST':
return redirect(url_for("add_ev"))
elif request.method == 'GET':
return render_template('add_cars.html')