Flask POST form error "Method Not Allowed" - python

I am trying to pass one parameter from text input form into my app.py but i got the following error message:
Method Not Allowed
The method is not allowed for the requested URL.
Herewith my app.py configuration:
#main_blueprint.route('/reports/daily_reports')
def downloadsss():
if request.method == 'GET':
daily_path = "./app/templates/Repo/DailyReports"
daily_listOfFiles = os.listdir(daily_path)
return render_template('main/DailyReports.html', len = len(daily_listOfFiles), daily_listOfFiles
= daily_listOfFiles)
elif request.method == 'POST' and 'download' in request.form:
download = request.form.get('download')
path = 'C:/Users/Ahmed Mustafa/FlaskProject/app/templates/Repo/DailyReports/' + download
return send_file(path, as_attachment=True)
and the following is my HTML code:
{% extends "main/main_base.html" %} {# main/main_base.html extends layout.html #}
{% block content %}
<head>
<style>
body {background-color: powderblue;}
h1 {color: blue;}
p {color: red;}
h2 {color: black; font-size: 20px; font-family: "Lucida Sans Unicode", "Lucida Grande", sans-
serif;}
th {vertical-align: top; align-items: center;}
table{align-items: center; }
</style>
<div class="jumbotron text-center">
<p><font size="6">This page is to show the Daily Reports list!</font></p>
<form method="post">
<input type="text" name="download" />
<input type="submit" value="Download" />
</form>
<!-- For loop logic of jinja template -->
<li class="list-group-item"><font size="6">
{% print('Total Number of Reports:'), len %}</font></li>
<div align="left" >
{%for i in range(0, len)%}
{% print('Report Number:'),[i+1] %}
<li class="list-group-item">
<a href="file:///C:/Users/Ahmed
Mustafa/FlaskProject/app/templates/static/DailyReports/{{daily_listOfFiles[i]}}">
{{daily_listOfFiles[i]}}</a>
<p> </p>
<h2></h2>
</li>
{% endfor %}
</div>
</div>
{% endblock %}

You need to allow for a POST request on your route by adding POST to the methods argument of the route:
#main_blueprint.route('/reports/daily_reports', methods=('GET', 'POST'))

Related

Does PasswordResetConfirmView.py auto populate uid and token?

The view definitely does not populate on my end but password_reset_confirm.html in the demo template folder seems to do that.
password_reset_confirm_form.html
urls.py
path("dj-rest-auth/password/reset/confirm/<str:uid>/<str:token>/",
# TemplateView.as_view(template_name="password_reset_confirm.html"),
PasswordResetConfirmView.as_view(),
name='resend-email-verification'
),
Edit: maybe this webpage here is not the same page in django-rest-auth demo folder.
In django, it is defined as (in django code):
urls.py
path('reset/<uidb64>/<token>/',views.PasswordResetConfirmView.as_view(),name='password_reset_confirm'),
path('reset/done/',views.PasswordResetCompleteView.as_view(),name='password_reset_complete')
Then, you can customize according to your need and override it by inheriting it in your own views.py file.
Answer credits to GitHub user, riteshbisht.
What I am seeing is UI of browsable API of django rest framework that does not have this functionality for reading url and populating form field unless I tell it to.
For it to do this, I created templates/rest_framework/api.html file and inserted following code inside it:
api.html
{% extends "rest_framework/base.html" %}
{% block style %}
{{ block.super }}
<style>
#btn-link {
border: none;
outline: none;
background: none;
display: block;
padding: 3px 20px;
clear: both;
font-weight: 400;
line-height: 1.42857143;
color: #A30000;
white-space: nowrap;
width: 100%;
text-align: left;
}
#btn-link:hover {
background: #EEEEEE;
color: #C20000;
}
</style>
{% endblock %}
{% block userlinks %}
{% if user.is_authenticated or response.data.access_token %}
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
{% firstof user.username 'Registered' %}
<b class="caret"></b>
</a>
<ul class="dropdown-menu dropdown-menu-right">
{% url 'rest_user_details' as user_url %}
<li>User</li>
<li>
{% url 'rest_logout' as logout_url %}
<form action="{{ logout_url }}" method="post">
{% csrf_token %}
<button type="submit" id="btn-link">Logout</button>
</form>
</li>
</ul>
</li>
{% else %}
{% url 'rest_login' as login_url %}
<li>Login</li>
{% url 'rest_register' as register_url %}
<li>Register</li>
{% endif %}
{% endblock %}
{% block script %}
{{block.super}}
<script type="text/javascript">
var url_elements = window.location.pathname.split('/');
if (url_elements.length >= 3){
var uid = url_elements[url_elements.length - 3];
if (uid !== undefined){
$('input[name=uid]').val(uid);
}
var token = url_elements[url_elements.length - 2];
if (token !== undefined){
$('input[name=token]').val(token);
}
}
</script>
{% endblock %}

Images don't show correctly in a flask app

I'm trying to add avatar support to my flask app but i've encountered an interesting bug:
Im using the same sub-templates for _post and _comment on both of my home and user pages with links to images in static/uploads folder but these images only show inside my home template:
sub-template _post.html
<table class="table table-bordered">
<tr style="border: solid; border-color: #1B1C1C; border-width: 2px;">
<td width="70x" style="background-color: #DEE1E1; border-right: 1px solid grey;">
<a href="{{ url_for('user', username=post.author.username) }}">
<img height="150px" width="150px" src='static/uploads/{{post.author.username}}.jpg'>
</a>
<!-- <img style="border-style: solid; border-radius: 10%; border-color: black; border-width: 1px; background-color: white;" src="{{ avatars.robohash(post.author.username, size='80') }}" /> -->
</td>
<td>
<p><a href="{{ url_for('user', username=post.author.username) }}">
{{ post.author.username }}
</a>said: </p> <p style="margin-left: 90%; margin-top: -2%;">..at {{post.timestamp.replace(microsecond=0)}}</p>
<p style="width: 60%;" id="post{{ post.id }}">{{ post.body }}</p>
<div class="button" style="margin-left: 95%; margin-top: -2%;">
{% if current_user.liked_post(post) %}
&#128078
{% else %}
&#128077
{% endif %}
</div>
<p style="width: 11%;">{{ post.likes.count() }}&#128077</p>
</td>
</tr>
</table>
{% for comment in comments %}
{% if comment in post.comments %}
{% include "_comment.html" %}
{% endif %}
{% endfor %}
<p style="margin-bottom: 4%; margin-top: 1%;"><a style="border: solid; border-radius: 4%; border-color: black; border-width: 1px;
padding: 10px; margin-left: 10px; margin-top: 10%;" href="/comment/{{post.id}}"> Post Comment ▲</a></p>
sub-template _comment.html
<table class="table table-bordered" style="border-left: 7px solid; border-color: #30F153">
<tr style="border: solid; border-color: grey; border-width: 2px;">
<td width="70x" style="background-color: #E8E8E8; border-right: 1px solid grey;">
<a href="{{ url_for('user', username=comment.commenter.username) }}">
<img height="100px" width="100px" src='static/uploads/{{comment.commenter.username}}.jpg'>
</a>
<!-- <img style="border-style: solid; border-radius: 10%; border-color: black; border-width: 1px; background-color: white;" src="{{ avatars.robohash(comment.commenter.username, size='40') }}" /> -->
</td>
<td>
<p><a href="{{ url_for('user', username=comment.commenter.username) }}">
{{ comment.commenter.username }}
</a>commented: </p> <p style="margin-left: 90%; margin-top: -2%;">..at {{comment.timestamp.replace(microsecond=0)}}</p>
<p style="width: 60%;">{{ comment.body }}</p>
<div class="button" style="margin-left: 95%; margin-top: -2%; margin-bottom: -10%;">
{% if current_user.liked_comment(comment) %}
&#128078
{% else %}
&#128077
{% endif %}
</div>
<p style="width: 11%;">{{ comment.comment_likes.count() }}&#128077</p>
</td>
</tr>
</table>
template user.html
{% extends "base.html" %}
{% block app_content %}
<table style="margin-top: 1%; ">
<tr valign="top" style="width: 100%;">
<td>
<img height="400px" width="400px" src="/static/uploads/{{user.username}}.jpg">
</td>
<td>
<h3 style="margin-left: 1%;">{{ user.username }}</h3>
{% if user.about_me %}<p style="margin-left: 2%; width: 470%;">About me: {{ user.about_me }}</p>{% endif %}
<p style="margin-left: 2%;">Followers: {{ user.followers.count() }} Following: {{ user.followed.count() }}</p>
{% if user == current_user %}
<p style="margin-left: 2%;"></p>
{% elif not current_user.is_following(user) %}
<p style="margin-left: 2%;">Follow</p>
{% else %}
<p style="margin-left: 2%;">Unfollow</p>
{% endif %}
</td>
</tr>
</table>
<div style="margin-top: 1%;">
{% for post in posts %}
{% include "_post.html" %}
{% endfor %}
</div>
{% endblock %}
template home.html
{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}
{% block app_content %}
<h2>Hi, {{current_user.username}}</h2>
{% if form %}
{{ wtf.quick_form(form, button_map={'submit':'btn btn-outline-dark'}) }}
<br>
{% endif %}
{% for post in posts %}
{% include "_post.html" %}
{% endfor %}
{% endblock %}
my view functions:
# user page
#login_required
#app.route('/user/<username>')
def user(username):
if current_user.is_authenticated:
user = User.query.filter_by(username=username).first_or_404()
posts = user.posts.order_by(Post.timestamp.desc())
comments = Comment.query.all()
return render_template('user.html', title='User Page', user=user, username=current_user.username,
posts=posts, comments=comments)
return redirect(url_for('login'))
# home page
#login_required
#app.route('/', methods=['POST', 'GET'])
#app.route('/home', methods=['POST', 'GET'])
def home():
if current_user.is_authenticated:
form = PostForm()
if form.validate_on_submit():
post = Post(body=form.post.data, author=current_user)
db.session.add(post)
db.session.commit()
flash('Your post has been posted!')
return redirect(url_for('home'))
posts = Post.query.order_by(Post.timestamp.desc()).all()
comments = Comment.query.all()
return render_template('home.html', title='Home', form=form, username=current_user.username,
posts=posts, comments=comments)
return redirect(url_for('login'))
now for some reason when i look at the link to a post avatar from home page the path looks like this:
http://127.0.0.1:5000/static/uploads/image.jpg
and when im looking at an image from my user page it looks like this:
http://127.0.0.1:5000/user/static/uploads/SLDem.jpg
i'm guessing it has something to do with my route function having multiple sections but the avatar itself on the user page displays correctly..
You forgot a '/' in the _post.html and _comment.html in the img src. (?)
partials (post, comment)
<img height="150px" width="150px" src='static/uploads/{{post.author.username}}.jpg'>
user.html
<img height="400px" width="400px" src="/static/uploads/{{user.username}}.jpg">
url_for is also usable for static files:
{{ url_for('static', filename='css.css') }}
Link to Flask static files with url_for

My app.py is not able to recive the request at the backend and getting 404 error

My app.py is
app=flask.Flask(__name__,template_folder='templates')
#app.route('/')
def main():
if flask.request.method == 'GET':
return(flask.render_template('main.html'))
if flask.request.method == 'POST':
news = flask.request.form['article']
input_variables = pd.DataFrame([[news]],
columns=['news'],
dtype=object)
prediction = model.predict(input_variables)[0]
return flask.render_template('main.html',
original_input={'news':news},
result=prediction,
)
if __name__=='__main__':
app.run()
<!doctype html>
<html>
<style>
form {
margin: auto;
width: 35%;
}
.result {
margin: auto;
width: 35%;
border: 1px solid #ccc;
}
</style>
<head>
<title>News Classification Model</title>
</head>
<form action="{{ url_for('main') }}" method="POST">
<fieldset>
<legend>Input values:</legend>
Enter any news:
<input name="news" type="object" required>
<br>
<br>
<input type="submit">
</fieldset>
</form>
<br>
<div class="result" align="center">
{% if result %}
{% for variable, value in original_input.items() %}
<b>{{ variable }}</b> : {{ value }}
{% endfor %}
<br>
<br> Predicted Class of the news :
<p style="font-size:50px">{{ result }}</p>
{% endif %}
</div>
</html>
I think I'm having a problem in html file so any help would be great to rectify it.
I'm new to Flask so i'm not able to solve it.My main.html file I've taken from someone so thats why i guess I'm having this Problem.
You need to delete the blank line between these two lines:
#app.route('/')
def main():

how to display google map in between the dashboard

while running flask server throwing this error Uncaught TypeError: Cannot read property 'firstChild' of null at Object._.Og (js?key=AIzaSyAbZKo3h1LVhyoURgxcSUG9BGVvZtZpg0U:88) at new Sg (js?key=AIzaSyAbZKo3h1LVhyoURgxcSUG9BGVvZtZpg0U:89)
I'm new google maps in Python-Flask.google map is not showing while running the Flask localhost server.but,it showing while running the template.i'm not aware where i have mistaken in my source code. I need only show the map in between the empty place. here is the dashboard where place be the map here
yesterday i posted answer that is working.but it's showing like Uncaught TypeError: Cannot read property 'firstChild' of null at Object._.Og (js?key=AIzaSyAbZKo3h1LVhyoURgxcSUG9BGVvZtZpg0U:88) at new Sg (js?key=AIzaSyAbZKo3h1LVhyoURgxcSUG9BGVvZtZpg0U:89) where is the problem
Here is the google map code:
{% extends "base.html" %}
{% block head %}
{{super()}}
{% endblock %}
{% block navbar %}
{{super()}}
{% endblock %}
{% block content %}
<div class="row">
<ol class="breadcrumb">
<li><a href="#">
<em class="fa fa-home"></em>
</a></li>
<li class="active">Locations>create locations</li>
</ol>
</div><!--/.row-->
<div class="row">
<div class="col-md-6">
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?key=AIzaSyDv8X0eEAWUtWZrHG_1XLB8gMNxgdcD0-U"></script>
<script >
window.onload = function () {
var mapOptions = {
center: new google.maps.LatLng(17.3850, 78.4867),
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var infoWindow = new google.maps.InfoWindow()
var name;
var lat;
var lng;
var latlngbounds = new google.maps.LatLngBounds();
var map = new google.maps.Map(document.getElementById("dvMap"), mapOptions);
google.maps.event.addListener(map, 'click', function (e) {
var latlng = new google.maps.LatLng(e.latLng.lat(), e.latLng.lng());
var geocoder = geocoder = new google.maps.Geocoder();
var marker = new google.maps.Marker({
position: latlng,
map: map,
title: 'Hello World!'
});
geocoder.geocode({ 'latLng': latlng }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[1]) {
name= results[1].formatted_address;
lat=e.latLng.lat();
lng=e.latLng.lng();
alert("Location: " +name + "\r\nLatitude: " + lat + "\r\nLongitude: " +lng );
document.getElementById("loc").value=name;
document.getElementById("lat").value=lat;
document.getElementById("lng").value=lng;
}
}
});
});
}
</script>
<!--<div id="dvMap" style="width: 50%; height: 50%">-->
<!--</div>-->
<form role="form" action="/post/locations" method="post" >
<input type="text" id="loc" name="name" class="form-control"/>
<input type="text" name="latitude" id="lat" class="form-control"/>
<input name="longitude" id="lng" type="text" class="form-control"/>
<input type="submit" class="btn btn-primary" value="Submit">
<input type="reset" class="btn btn-default" value="Reset">
</form>
</div>
</div>
<div id="dvMap" style="width: 80%; height: 70% ">
</div>
{% endblock %}
Here is the Python code:
#app.route('/page/locations')
def location():
if session['username']:
return render_template('map.html',user=session['username'])
else:
print ('login first!')
return redirect('/dashboard')
I just found the answer.Here it is my answer.
{% extends "base.html" %}
{% block head %}
{{super()}}
{% endblock %}
{% block navbar %}
{{super()}}
{% endblock %}
{% block content %}
<div class="row">
<ol class="breadcrumb">
<li><a href="#">
<em class="fa fa-home"></em>
</a></li>
<li class="active">Locations>Create Locations</li>
</ol>
</div><!--/.row id="entry.id" id="uploadbanner"-->
<div id="dvMap" style="width: 100%; height: 100%">
</div>
<form role="form" action="/post/locations" method="post">
<label>Name:</label>
<input type="text" id="loc" name="name"/>
<label>Latitude:</label>
<input type="text" name="latitude" id="lat"/>
<label>Longitude:</label>
<input name="longitude" id="lng" type="text"/>
<input type="submit" class="btn btn-primary" value=" Submit ">
<input type="reset" class="btn btn-default" value="Reset">
</form>
{% endblock %}
I just add the script in Javascript folder .
as a like <--static/assets/js/map.js --> in my template base.html source code.
The problem with your code is the javascript snippet is getting executed before the div element ( one with id="dvMap" ) is created. So either place the javascript snippet after the div element like below,
{% extends "base.html" %}
{% block head %}
{{super()}}
{% endblock %}
{% block navbar %}
{{super()}}
{% endblock %}
{% block content %}
<div class="row">
<ol class="breadcrumb">
<li><a href="#">
<em class="fa fa-home"></em>
</a></li>
<li class="active">Locations>create locations</li>
</ol>
</div>{# /.row #}
<div class="row">
<div class="col-md-6">
{# <div id="dvMap" style="width: 50%; height: 50%"></div> #}
<form role="form" action="/post/locations" method="post" >
<input type="text" id="loc" name="name" class="form-control"/>
<input type="text" name="latitude" id="lat" class="form-control"/>
<input name="longitude" id="lng" type="text" class="form-control"/>
<input type="submit" class="btn btn-primary" value="Submit">
<input type="reset" class="btn btn-default" value="Reset">
</form>
</div>
</div>
<div id="dvMap" style="width: 80%; height: 70% ">
</div>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?key=AIzaSyDv8X0eEAWUtWZrHG_1XLB8gMNxgdcD0-U"></script>
<script >
window.onload = function () {
var mapOptions = {
center: new google.maps.LatLng(17.3850, 78.4867),
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var infoWindow = new google.maps.InfoWindow()
var name;
var lat;
var lng;
var latlngbounds = new google.maps.LatLngBounds();
var map = new google.maps.Map(document.getElementById("dvMap"), mapOptions);
google.maps.event.addListener(map, 'click', function (e) {
var latlng = new google.maps.LatLng(e.latLng.lat(), e.latLng.lng());
var geocoder = geocoder = new google.maps.Geocoder();
var marker = new google.maps.Marker({
position: latlng,
map: map,
title: 'Hello World!'
});
geocoder.geocode({ 'latLng': latlng }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[1]) {
name= results[1].formatted_address;
lat=e.latLng.lat();
lng=e.latLng.lng();
alert("Location: " +name + "\r\nLatitude: " + lat + "\r\nLongitude: " +lng );
document.getElementById("loc").value=name;
document.getElementById("lat").value=lat;
document.getElementById("lng").value=lng;
}
}
});
});
}
</script>
{% endblock %}
Or make a separate js file ( here I have named it custom.js for an example ) in the static folder with the javascript code in it and add <script src='{{ url_for('static', filename='custom.js') }}'></script> at the end of the file.
I hope this helps you.
PS :- Please use the jinja2 comment tags while commenting in jinja2 template file. You can refer it here.

How to get input either from a form or as uploaded input file in Django?

I have written a view which takes input either from a form where you can post your data directly or you can upload a ".csv" file like this given below:
views.py
def Some_view(request):
if request.method == 'POST':
form = My_form(request.POST)
else:
request.method == 'POST' and request.FILES['myfile']
myfile = request.FILES['myfile']
fs = FileSystemStorage()
filename = fs.save(myfile.name, myfile)
uploaded_file_url = fs.url(filename)
return render(request, 'myapp/des.html')
return render(request, 'myapp/des.html', {'form': form})
html template: des.html is like this:
{% extends 'protocol/base.html' %}
{% load staticfiles %}
<!DOCTYPE html>
<html>
<head>
<title></title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
{% block content %}
<body>
<div class="container">
<div style="width:30%">
<form action="/result_view/" method="post">
{%csrf_token%}
{% for error in form.non_field_errors %}
<div class="form-group has-errors text-danger small">
{{error}}
</div>
{% endfor %}
{% for field in form %}
<div class="form-group has-errors text-danger small">
{{field.errors}}
</div>
<div class="form-group has-errors text-danger small">
</div>
{% endfor %}
<div class="form-group">
{{form.AA}}
</div>
<div class="form-group">
<button class="btn btn-primary" style="width:100%; margin-bottom: 30px ">Submit</button>
</div>
<h2> or <h2>
<style type="text/css">
.button {
background-color: #ff9800; /* Green */
border: none;
color: black;
padding: 10px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin-top: 10px;
margin-bottom: 30px;
}
</style>
<form method="post" enctype="multipart/form-data">
<div class="heading">
</h4>
</div>
{% csrf_token %}
<input class="input" type="file" name="myfile">
<button class="button" type="submit">Upload</button>
</form>
{% if uploaded_file_url %}
<p class="text" >File uploaded successfully. </p>
{% endif %}
</div>
</form>
</div>
</body>
</html>
{% endblock %}
forms.py
from django import forms
class My_form(forms.Form):
AA = forms.CharField(widget=forms.Textarea(attrs={'class':'form-control','placeholder':'Ex.: ARNDCEQGHILKMFPSTWYV'}))
class Meta:
fields = ['AA']
The form is working fine but in my case upload method is not working, when I use to upload file method alone if works fine but with form method, it is not working please help me out in this regards thanks.
i think you need to change if condition sequence:
if request.method == 'POST' and request.FILES.get('myfile'):
# You code here
elif request.method == 'POST':

Categories

Resources