Flask redirect to url_for - python

I have he following data_analytics.html` which in the end provides the
view:
{% extends 'base.html' %} {% block title %}Home{% endblock %}
{% block content %}
<!-- <h1 align="center" >Your Files</h1> -->
<br />
<table class="table table-bordered table-hover">
<caption> Files Uploaded</caption>
<tr>
<th class="table-light"> # </th>
<th class="table-light">File Name</th>
<th class="table-light">Date</th>
<th class="table-light">Access Data</th>
</tr>
{% for file in csv_file %}
<tr>
<!-- <td>{{ file.id }}</td> -->
<th scope="row">1</th>
<td>{{ file.data }}</td>
<td>{{ file.date }}</td>
<td>View Data</td>
{%endfor%}
</table>
{% endblock %}
Is there a way that when the user clicks on the link to have displayed the content of the .csv file using python/flask ?
Tried to create a function that redirects to an url_for but not working`

try this:
In this 'a' put a 'target="_blank"'
View Data
And, in the python let's create a new function:
from flask import send_from_directory
#app.route('/csv')
def see_file():
return send_from_directory(directory='static', path='files/cheat_sheet.pdf')
Just change the path and the directory. And the file is going to open in a new tab.

Related

How to get the value of input on button click in django

I have a django template as follows
<table class="table">
<thead>
<tr>
<th>#</th>
<th>Master Title</th>
<th>Retailer title</th>
<th>To add</th>
</tr>
</thead>
<tbody>
{% if d %}
{% for i in d %}
<tr>
<th scope="row">{{forloop.counter}}</th>
<td>{{i.col1}}</td>
<td>{{i.col2}}</td>
<td>
<input type="hidden" name='row_value' value="{{i.col1}}|{{i.col2}}">
<a class='btn btn-success' href="{% url 'match' %}">Match</a>
<a class='btn btn-outline-danger' href="{% url 'mismatch' %}">Not a Match</a>
</td>
</tr>
{% endfor %}
{% endif %}
</tbody>
</table>
When the match button is clicked, I want to retrieve the value of the hidden input in the views. Here is my views.py
def match(request):
print(request.GET.get('row_value'))
print('match')
But this returns None.
I want the values of col1 and col2 to be printed as follows
col1|col2
I am not sure where I am going wrong.
You should use Django URL params with GET:
urls.py
urlpatterns = [
path('your-path/<int:first_param>/<int:second_param>', views.match),
]
source: https://docs.djangoproject.com/en/3.2/topics/http/urls/#example
views.py
def match(request, first_param=None, second_param=None):
# then do whatever you want with your params
...
source: https://docs.djangoproject.com/en/3.2/topics/http/urls/#specifying-defaults-for-view-arguments
template:
<td>
<a class='btn btn-outline' href="your-path/{{i.col1}}/{{i.col2}}">Example</a>
</td>
This is a basic example, so change it to your use case.

Django: select all data from a row in a html table and use them in a view

I am new to both django and web development.
The task is to run a script when pressin a button using the data contained in the specific row of an html table.
So if i clik on the second button "Run script" it uses all the data in that row (8888, 2020/06/21 06:00) in a separate script to performe some task.
Currently my html file looks like this:
There are 2 sections one for uplading the information that goes in the table one the table which displays them
<h1>Approach Path KML Generator</h1>
<h2>Generate the KML file here:</h2> <form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button onclick="location.href='{% url 'approach_path_receptorsKML:Proejct Creator' %}'">Upload</button> </form>
<h2>Projects Available:</h2>
<table class="table">
<thead>
<tr>
<th>Project ID</th>
<th>Date KML</th>
<th>Time KML</th>
<th>Date-Time Uploaded</th>
<th>Run The Conversion</th>
<th>KML File</th>
</tr>
</thead>
<tbody>
{% for project in latest_project_list %}
<tr>
<td>{{ project.project_ID }}</td>
<td>{{ project.date_kml }}</td>
<td>{{ project.time_kml }}</td>
<td>{{ project.upload_time }}</td>
<td>
<button method="post" value="collect data" name="{{ project.project_ID }}|{{ project.date_kml }}|{{ project.time_kml }}|{{ project.upload_time }}">Run script</button>
</td>
<td>
Download KML File
</td>
</tr>
{% endfor %}
</tbody> </table>
And this is the view I have created:
def ProjectCreator(request):
form = DocumentForm()
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid:
form.save()
elif 'collect data' in request.POST.values():
values = [key for key in request.POST.keys()]
print(values)
else:form = DocumentForm()
I have tried to use this guide (How do I pass table data from a template over to Django on a button/submit click?) however, I have been insuccesfull.
If anyone can spot the mistake I have made and give me some explanation I would be grateful.
Thanks
It doesn't work because you have incorrect HTML layout. Button itself doesn't do anything - in order to send POST request, it should be in <form> tag. Try following:
{% for project in latest_project_list %}
<tr>
<td>{{ project.project_ID }}</td>
<td>{{ project.date_kml }}</td>
<td>{{ project.time_kml }}</td>
<td>{{ project.upload_time }}</td>
<td>
<form method="post">
{% csrf_token %}
<button value="collect data"
name="{{ project.project_ID }}|{{ project.date_kml }}|{{ project.time_kml }}|{{ project.upload_time }}">
Run script
</button>
</form>
</td>
<td>
Download KML File
</td>
</tr>
{% endfor %}
This will work, but I doubt this is great way of achieving this. You can just send project.pk with POST request and fetch project in view. This way you can be sure user will not send incorrect/malicious data with request. It is especially important since your code will run script based on data.

Create a custom URL and outputting HTML form data

For my first Flask project I wanted to create a basic Flask app using Riot Game's API for League of Legends. I've got all the processing of API working but I'm having trouble going about outputting it.
I take the input from a form on one page.
<form class="navbar-form navbar-left" action="{{ url_for('current_game_output') }}" method="POST">
<div class="form-group">
<input type="text" class="form-control" placeholder="Summoner Name" name="summoner_name">
<select class="form-control" name="region">
<option value="oce">Oceanic</option>
<option value="na">North America</option>
<option value="euw">Europe West</option>
</select>
</div>
<button type="submit" class="btn btn-default" value="Send">Submit</button>
</form>
And I am trying to output the data returned from the API onto the next page.
{% extends "header.html" %}
{% block body %}
<h3> Team 2 </h3>
<table class="table table-bordered" width="50%">
<tr>
<th width="48%">Summoner Name</th>
<th width="48%">Champion</th>
<th width="4%">Pic</th>
</tr>
{% for player in team1 %}
<tr>
<td>{{ player[0] }}</td>
<td>{{ player[1] }}</td>
<td><img width="20px" src="{{ url_for('static', filename='images/championIcons/') }}{{ player[1].replace(" ", "") }}_Square_0.png"></td>
</tr>
{% endfor %}
</table>
<h3> Team 1 </h3>
<table class="table table-bordered" width="50%">
<tr>
<th width="48%">Summoner Name</th>
<th width="48%">Champion</th>
<th width="4%">Pic</th>
</tr>
{% for player in team2 %}
<tr>
<td>{{ player[0] }}</td>
<td>{{ player[1] }}</td>
<td><img width="20px" src="{{ url_for('static', filename='images/championIcons/') }}{{ player[1].replace(" ", "") }}_Square_0.png"></td>
</tr>
{% endfor %}
</table>
{% endblock %}
I'd like the URL of the output page to be dynamic'/currentgame/region/username' but keep getting errors when trying to do so.
Relevant part of my views.py file (hidden my api key):
#app.route('/header')
def header():
return render_template("header.html")
#app.route('/current')
def current():
return render_template("current.html")
#app.route('/currentgame/<region>/<name>', methods=['POST'])
def current_game_output(region, name):
region = request.form['region']
summoner_name = request.form['summoner_name']
api = RiotAPI('APIKEYGOESHERE', region)
team1, team2 = current_game_data(summoner_name, region, api)
return render_template("output.html",team1=team1,team2=team2)
Any help/pointers on the best way to output/return the data would be appreciated.
Thanks
You should post the error as well.
In a quick looks this should be fixed:
#app.route('/currentgame/<string:region>/<string:name>', methods=['POST'])
def current_game_output(region, name):
region = request.form['region']
summoner_name = request.form['summoner_name']
api = RiotAPI('APIKEYGOESHERE', region)
team1, team2 = current_game_data(summoner_name, region, api)
return render_template("output.html",team1=team1,team2=team2)
Change route to /currentgame/<string:region>/<string:name>

Django HTML to PDF with links and dynamic data

I have Django 1.7.1 and Python 2.7.8
I want to get a PDF from a rendered html template, I have tried PISA (xhtml2pdf) but first, i had a lot of problems with Bootstrap css, then, after deleting some lines, this message appeared:
'CSSTerminalFunction' object has no attribute 'lower'
'lower' seems to be part of python 3 and not available in 2.7 (If I am wrong, please tell me)
Now I am trying to use wkhtmltopdf but the documentation is too basic. It describes only one simple example with static HTML
Can someone explain how I can get a PDF with my actual template?
In the template, i have 2 links to css files, and one Image (logo)
I have some bootstrap css style, and i want to use it if possible
I put a "queryset" (actually a tuple) in the template to be rendered inside a table
I also put some string parameters to be rendered in deferent locations in my html.
Here is a part of the template
{% extends 'reporteBase.html' %}
{% block titulo %}Reporte - Inventario por UbicaciĆ³n{% endblock %}
{% block content %}
{% if productos %}
<h2>Inventario de la ubicaciĆ³n "{{ ubi }}"</h2>
<div class="row" style="margin-top: 2em">
<table class="table table-condensed" data-resizable-columns-id="demo-table">
<thead>
<tr>
<th data-resizable-column-id="mod">Modelo/Item</th>
<th data-resizable-column-id="desc">Descripcion</th>
<th data-resizable-column-id="cant" data-noresize>Cantidad</th>
<th data-resizable-column-id="unidad" data-noresize>Unidad</th>
<th data-resizable-column-id="ubi" data-noresize>Ubicacion</th>
</tr>
</thead>
<tbody>
{% for p in productos %}
<tr>
<td>{{ p.producto__item}}</td>
<td>{{ p.producto__descripcion }}</td>
<td>{{ p.sum_cantidad }}</td>
<td>{{ p.producto__unidad }}</td>
<td>{{ p.ubicacion__nombre }}</td>
</tr>
{% empty %}
<tr><td colspan=4>No hay Productos</td></tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
{% endblock %}
Thanks!
A view needs to render the template as a PDF. That's what the code from the django-wkhtmltopdf Simple Example does.
Try rendering the page as HTML first to make sure the template is working. You could do this with a view like:
url(r'^html_preview/$',
TemplateView.as_view(template_name='pdf_template.html'))
After you've solved any issues with the template, then try it with PDFTemplateView.

mustache, babel and gettext

I am using Flask, jinja together with Mustachjs.
In order to get the job done I am using the {% raw %} tag.
Now, it is a multi-languages application and I use Babel.
How can I do :
{% raw %}
<script id="details" type="text/template">
<table class="table" >
<thead>
<tr>
<th>**{{gettext('col1')}}</th>
<th>**{{gettext('col2')}}</th>
<th>**{{gettext('col6')}}</th>
</tr>
</thead>
<tbody>
{{#skyrsla}}
<tr>
<td> {{index}}</td>
<td> {{nafn}}</td>
<td> {{mean_growth_index}}</td>
</tr>
{{/skyrsla}}
</tbody>
</table>
</script>
{% endraw %}
Since it is between raw tags, the Babel extension does not detect {{gettext('col1')}
Is there a way to alter the configuration of Babel.
My actual configuration looks like :
[python: **.py]
[jinja2: **/templates/**.html]
extensions=jinja2.ext.autoescape,jinja2.ext.with_
Simply end your raw blocks between calls to gettext:
{% raw %}
<script id="details" type="text/template">
<table class="table" >
<thead>
<tr>
<th>**{% endraw %}{{gettext('col1')}}{% raw %}</th>
<th>**{% endraw %}{{gettext('col2')}}{% raw %}</th>
<th>**{% endraw %}{{gettext('col6')}}{% raw %}</th>
</tr>
</thead>
<tbody>
{{#skyrsla}}
<tr>
<td> {{index}}</td>
<td> {{nafn}}</td>
<td> {{mean_growth_index}}</td>
</tr>
{{/skyrsla}}
</tbody>
</table>
</script>
{% endraw %}

Categories