I'm trying to create a button in my HTML that will go to the next/previous page when the button is clicked. I've tried pagination and peewee but didn't seem to get it to work.
Here is my app:
from flask import Flask,render_template, request, json
from flask_mysqldb import MySQL
app = Flask(__name__)
app.config['MYSQL_HOST'] = 'example'
app.config['MYSQL_USER'] = 'example'
app.config['MYSQL_PASSWORD'] = 'example'
app.config['MYSQL_DB'] = 'fund_raiser'
mysql = MySQL(app)
#app.route('/funds/pages/', defaults={'page':0})
#app.route('/funds/pages/<int:page>')
def fund_pages(page):
perpage = 5
first_page = page*perpage
cur = mysql.connection.cursor()
cur.execute("select * from fund_table limit "+str(first_page)+", "+str(perpage)+";", mysql.connection.commit())
data = cur.fetchall()
return render_template('funds.html', data=data)
Where do I add the href tag in my html page? What is the correct variable to use?
This is quite easy with the url_for() function.
You can call the name of the function for the route, and pass it a variable.
href="{{ url_for('fund_pages', page=page_num) }}"
Where page_num is the page number.
To get the page number dynamically, you can simple add or subtract 1 from the current page number. For example, you could store page_prev = current_page - 1 and page_next = current_page + 1.
You can these pass those variables to the url_for function as the page parameter.
Example:
# in fund_pages()
prev_page = page - 1
next_page = page + 1
return render_template('template.hmtl', next_page=next_page, prev_page=prev_page)
# in the template
Previous
Next
Related
I am following the CS50 of Harvard and I don't want to use CS50 library that they use for lecture purposes, but I could not figure out how to make this code work. A little help would be greatly appreciated
import sqlite3
from flask import Flask, redirect, render_template, request, session
from flask_session import Session
# Configure app
app = Flask(__name__)
# Connect to database
db = sqlite3.connect("store.db",check_same_thread=False)
c = db.cursor()
# Configure sessions
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
Session(app)
#app.route("/")
def index():
books = db.execute("SELECT * FROM books")
list =[dict(id=book[0], title=book[1]) for book in books.fetchall() ]
return render_template("books.html", books=list)
#app.route("/cart", methods=["GET", "POST"])
def cart():
# Ensure cart exists
if "cart" not in session:
session["cart"] = []
# POST
if request.method == "POST":
id = request.form.get("id")
if id:
session["cart"].append(id)
return redirect("/cart")
# GET
books = db.execute("SELECT * FROM books WHERE id IN (?)", [session("cart")])
list =[dict(id=book[0], title=book[1]) for book in books.fetchall()]
return render_template("cart.html", books=list)
The error is at the books=db.execute... line.
Error is :
sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 1, and there are 9 supplied
I pressed the cart button 9 times, it is incrementing. Tried other solutions, could not still figure out.
books = db.execute("SELECT * FROM books WHERE id IN (?)", [session("cart")])
should be
query = f"SELECT * FROM books WHERE id IN ({','.join(['?'] * len(session['cart']))})"
books = db.execute(query,session['cart'])))
'''
app.py
from flask import Flask, render_template, request
from weather_backend import temperature_condition,clothes,feels_temperature,weather_description
app = Flask(__name__)
app.config["SECRET_KEY"] = "Secret-key"
#app.route("/")
def index():
return render_template("index.html")
#app.route("/dress")
def dress():
cityname = request.form.get("city_name")
temp = str(temperature_condition())
message = str(clothes())
feels = feels_temperature
description= weather_description
return render_template("dress.html", message=message, temp=temp, feels_temperature=feels,
weather_description=description )
if __name__ == "__main__":
app.run(debug=True)
'''
'''
weather_backend.py
import requests, json
import weatherMappingMessage
from app import dress
from keys import *
base_url = "http://api.openweathermap.org/data/2.5/weather?"
city_name =
complete_url = base_url + "appid=" + api_key + "&q=" + city_name + "&units=metric"
response = requests.get(complete_url)
'''
HTML file
'''
<body>
<div class="head">
<form action= "{{ url_for('dress') }}" class="form" method="GET">
<h1>Get Weather and Dresses according to the Weather</h1>
<div class = "form-box">
<input type="text" class="search-field location" name= "city_name" placeholder="Location...">
<button class="search-btn" type="button">Search</button>
</div>
</form>
</div>
</body>
'''
I need to get the form info(search) from HTML to the backend(city_name) and then to the flask(cityname)
I can get a message from the backend if try to get it but I can't get HTML form to the backend for processing
The problem I'm facing is that I can't get the form data from my HTML file to my backend for processing
basically, I need the cityname to the backend for getting my weather description
Short answer:
Because your form submission uses a get request, you can use request.args to get parsed contents of query string (see also):
cityname = request.args.get("city_name")
Long answer:
I'm sure you're asking for more than just this piece of code. I took the code you provided and added the missing pieces in-line (please don't do this for production code) and also passed cityname to render_template:
import logging
from datetime import datetime
from flask import render_template, request
from app import app, forms
#app.route("/")
def index():
return render_template("index.html")
#app.route("/dress")
def dress():
cityname = request.args.get("city_name")
# missing in example code
def temperature_condition():
return 'temp cond'
# missing in example code
def clothes():
return 'clothes'
feels_temperature = 'feels temp' # missing in example code
weather_description = 'weather desc' # missing in example code
temp = str(temperature_condition())
message = str(clothes())
feels = feels_temperature
description = weather_description
return render_template("dress.html", message=message, temp=temp, feels_temperature=feels,
weather_description=description, cityname=cityname) # also pass cityname
I created a minimalistic dress.html:
<html>
<body>
<p>message = {{ message }}</p>
<p>temp = {{ temp }}</p>
<p>feels_temperature = {{ feels_temperature }}</p>
<p>weather_description = {{ weather_description }}</p>
<p>cityname = {{ cityname }}</p>
</body>
</html>
Starting the application via flask run allows me to input a city name into the form field and view the results (for example 'Berlin'):
In order to show the weather description for the chosen city, you could create a function that accepts the city name and retrieves the information from the web (just a rough sketch):
import requests, json
import weatherMappingMessage
from app import dress
from keys import *
def weather_for_city(city_name):
base_url = "http://api.openweathermap.org/data/2.5/weather?"
complete_url = base_url + "appid=" + api_key + "&q=" + city_name + "&units=metric"
response = requests.get(complete_url)
if response.status_code == 200:
return response.json() # assumes your API returns a JSON response
else:
# perform some error handling here, maybe apply a retry strategy
pass
Extract the relevant data from the result of weather_for_city and pass it to render_template like you did for the other variables.
I have a function which displays the live location of a vehicle on demand. There are two functions and thus buttons, when clicked should run a code internally, and display the result on this same view/page. I am not able to understand how to create those two functions, without reloading my page or going to another page. I do not have to pass any kind of arguments in the function from the template, as of now. Is this possible in django??
Code
Here is my function in my view.py
#method_decorator([login_required, teacher_required], name='dispatch')
class QuizResultsView(DetailView):
model = Quiz
context_object_name = 'quiz'
template_name = 'classroom/teachers/quiz_results.html'
tripId = str()
def start_trip(self):
quiz = self.get_object()
lr_object = get_object_or_404(LR, lr_quiz=quiz.id)
# ----------Call api to fetch location code -----------#
My api fetch code will return a json object which I have to parse and enter the same in a Google Iframe, and it takes about 2-3 seconds to populate the iframe.
I have many 'mini-functions' or whatever they are called in my same function, just like :
def get_queryset (self):
return self.request.user.quizzes.all()
Hence, is there a way to create more functions just like these? Also, how will I call such functions from my templates? Is there any other way of creating a view, where I can have multiple buttons, with individual functions to each button, and it does not reload the page or go to any other page ?
Complete Code
def start_trip (self):
quiz = self.get_object()
lr_object = get_object_or_404(LR, lr_quiz=quiz.id)
print("#271 lr_object.driver_name", lr_object.driver_name)
gmaps = googlemaps.Client(key=###)
driver_num = lr_object.driver_name
origin = lr_object.lr_consignee_address # origin from lR
dest = lr_object.lr_consignor_address # dest from LR
geocode_result_orig = gmaps.geocode(origin)
geocode_result_orig = gmaps.geocode(origin)
lat_orig = str(geocode_result_orig[0]["geometry"]["location"]["lat"])
lon_orig = str(geocode_result_orig[0]['geometry']['location']['lng'])
geocode_result_dest = gmaps.geocode(dest)
lat_dest = str(geocode_result_dest[0]["geometry"]["location"]["lat"])
lon_dest = str(geocode_result_dest[0]['geometry']['location']['lng'])
url = 'https://sct.intutrack.com/api/prod/trips/start'
payload = 'tel=' + driver_num + '&src=' + lat_orig + '%2C%20' + lon_orig + '&dest=' + lat_dest + '%2C%20' + lon_dest + '&srcname=Intugine' \
'%20Technologies&destname=Bangalore&client=XYZ&vendor=Rivigo&vehicle=' \
'MH01x123&invoice=123ZXYZ&eta_hrs=75'
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
username = '###'
password = '###'
user_pass = (username, password)
response = requests.request('POST', url, headers=headers, data=payload, auth=user_pass)
response = response.json()
tripId = response["tripId"]
UPDATE:
I am thinking this can only be done with javascript, so I guess my question becomes 'How to pass django variables to a javascript function (without reloading the page ofc.)?'
I'm just learning Django, so my question might seem not worth attention, but i spent some time googling and havnt found an answer.
I have two models and a function to fill it
urls.py
url(r'^upd/$', update_database, name="upd")
views.py
def update_database(request):
grabdata()
def grabdata():
url = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/4.5_day.geojson"
weburl = urllib.request.urlopen(url)
if (weburl.getcode() == 200):
data = json.loads(weburl.read())
EarthQuakes.objects.all().delete()
LastGetSession.objects.all().delete()
lastsession = LastGetSession(hand=data["metadata"]["title"])
lastsession.save()
for i in data["features"]:
place = i["properties"]["place"]
place = str.split(",")
place = place[-1]
time = i["properties"]["time"]
mag = i["properties"]["mag"]
rept = i["properties"]["felt"]
if rept is None:
rept = 1
longitude = 0
latitude = 0
earthquake = EarthQuakes(place=place, time=time,
mag=mag, rept=rept,
longitude=longitude, latitude=latitude)
earthquake.save()
template
<a id="update_button" class="btn btn-info btn-lg" href="{% url 'upd' %}" >Update_database</a>
But i didn't get how to execute it from a view.
Or I assume there is a way to call a conroller function that calls the model function or something like that
It returns the "The view earthquake.views.update_database didn't return an HttpResponse object. It returned None instead."
It feels like there is one missing piece or the pazzle
On Your views.py
def my_view(request):
grabdata()
return HttpResponse('Done')
in urls.py add a new url
url(r'^my-view/$', views.my_view,name='my_view')
in your template
Update
I found here a nice template for a pagination. However, this example was done with SQLlite, but I rewrote in order to be able to use PyMongo.
This script creates users and save them to MongoDB with help of PyMongo:
import sys
from pymongo import MongoClient
def fill_data(users_no):
for i in range(users_no):
doc = {
'_id': str(i),
'uname': "name_" + str(i),
}
sDB.insert(doc)
if __name__ == '__main__':
db = MongoClient().test
sDB = db.users
fill_data(1000)
I modified the orginal app.py script in onrder to be able to use PyMongo. This is the modified script:
#!/usr/bin/env python
#-*- coding: utf-8 -*-
from __future__ import unicode_literals
from flask import Flask, render_template, g, current_app, request
from flask.ext.paginate import Pagination
from pymongo import MongoClient
app = Flask(__name__)
app.config.from_pyfile('app.cfg')
#app.route('/')
def index():
db_name = "test"
col_name = "users"
db = MongoClient()
sDB = db[db_name][col_name]
total = sDB.find().count()
print total
page, per_page, offset = get_page_items()
users = sDB.find().skip(offset).limit(per_page)
for u in users:
print u
pagination = get_pagination(page=page,
per_page=per_page,
total=total,
record_name=users,
)
return render_template('index.html', users=users,
page=page,
per_page=per_page,
pagination=pagination,
)
def get_css_framework():
return current_app.config.get('CSS_FRAMEWORK', 'bootstrap3')
def get_link_size():
return current_app.config.get('LINK_SIZE', 'sm')
def show_single_page_or_not():
return current_app.config.get('SHOW_SINGLE_PAGE', False)
def get_page_items():
page = int(request.args.get('page', 1))
per_page = request.args.get('per_page')
if not per_page:
per_page = current_app.config.get('PER_PAGE', 10)
else:
per_page = int(per_page)
offset = (page - 1) * per_page
return page, per_page, offset
def get_pagination(**kwargs):
kwargs.setdefault('record_name', 'records')
return Pagination(css_framework=get_css_framework(),
link_size=get_link_size(),
show_single_page=show_single_page_or_not(),
**kwargs
)
if __name__ == '__main__':
app.run(debug=True)
Is there a way to avoid to use count() by clicking to the next or previous page in the pagination menu?
What did I forget to change so the actual user get be shown in the browser, because currently I only get the pagination menu without users?
User this link, It w'll help to paginate datas using flask-paginate
https://harishvc.com/2015/04/15/pagination-flask-mongodb/
if you are not using Flask use:
https://scalegrid.io/blog/fast-paging-with-mongodb/
Hope it will help !