I'm pretty new to flask any web development in general. So I was wondering how you generate a link. as in, when somene registers on your website you create a link like site.com/leak1953 and that would be their profile.
For generating links there exists the function flask.url_for() which generates a URL given the endpoint with a method provided. You can use this function also in JINJA2 templates. To provide an external link use
{{ url_for('index.main', _external=True) }}
If you want to include parameters to the url just add them to the url_for parameters.
{{ url_for(show_user_profile, username='Klaus') }}
Variable Rules
To add variable parts to a URL you can mark these special sections as . Such a part is then passed as a keyword argument to your function. Optionally a converter can be used by specifying a rule with <converter:variable_name>.
#app.route('/user/<username>')
def show_user_profile(username):
# show the user profile for that user
return 'User %s' % username
#app.route('/post/<int:post_id>')
def show_post(post_id):
# show the post with the given id, the id is an integer
return 'Post %d' % post_id
source: http://flask.pocoo.org/docs/0.12/quickstart/#variable-rules
Related
I have a form and am passing the variable as below using Jinja template
<form action = "/user_data/{{period}}" method="POST">
It is not redirecting required page /user_data/Oct-2022
But while just using {{period}} for testing in html page, variable is returning the result as Oct-2022. Not sure why the same variable is not getting passed in the form action.
Variable is printing as below in html page,
{{period}}
But it is not printing in the form,
<form action = "/user_data/{{period}}" method="POST">
This is the route method,
#app.route("/user_listing/<period>", methods = ['POST', 'GET'])
def user_data(period):
....
....
return render_template('user_data.html', period=period)
First we imported the Flask class. An instance of this class will be our WSGI application.
Next we create an instance of this class. The first argument is the name of the application’s module or package. If you are using a single module (as in this example), you should use name because depending on if it’s started as application or imported as module the name will be different ('main' versus the actual import name). This is needed so that Flask knows where to look for templates, static files, and so on. For more information have a look at the Flask documentation.
We then use the route() decorator to tell Flask what URL should trigger our function.
The function is given a name which is also used to generate URLs for that particular function, and returns the message we want to display in the user’s browser.
I have a simple Flask web app. My index template has various ways of interacting with clients using javascript and HTML. I am also have a form that, upon submission, routes to another flask process and uses the request.form command to retrieve user-submitted data.
However, I want to do something a little different. I would like to initiate a Flask redirection upon javascript event but include a parameter, and not use form.
For example, my index.html file would display something like this after template rendering:
function startRedirect(parameter) {
window.location.pathname = '/myRedirect';
}
<input type="checkbox" id="sample" name="sample" onChange="startRedirect(parameter);">
And part of my Flask script would have:
#app.route('/myRedirect')
def myRedirectFunction():
# do something with the parameter here
return render_template('index.html')
I realize this can be done with using a form, but I am interested in accomplishing this task without having a form. I was thinking about somehow using request.args, but don't quite understand what to do.
You can use a dynamic route to capture a simple input and pass it to the route's function.
app.route('/myRedirect/<param>')
def myRedirectFunction(param='hello world'):
return render_template('index.html', param=param)
Using this route as a redirect, you can pass a single param (or multiple if you serialize them) that you can use to do something. From there, you can either display or you can redirect again to a common endpoint so the user does not see the param in the url.
There's no need for a form or an explicit redirect, just attach a route and some parameter to the dynamic route.
Let's say you have a model to list the departments in your company:
class Departments(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), unique=True)
Now you have a department selection page:
#app.route('/departments_home', methods=['GET'])
def departments_home():
departments = Departments.query.all()
return render_template('departments_home.html',
departments=departments)
On the frontend you might have a variety of selections, each giving a link to the same route but with a different department_id:
{% for department in departments %}
Click to go to {{ department.name }}
{% endfor %}
Now you just need another route to handle this, taking the variable department_id that was passed in the GET request:
#app.route('/load_department/<department_id>', methods=['GET'])
def load_department(department_id):
department = Departments.query.get(int(department_id))
department_data = # do stuff here with the specific department
This question already has answers here:
Sending data from HTML form to a Python script in Flask
(2 answers)
How to use variables in SQL statement in Python?
(5 answers)
Closed 3 years ago.
I'm trying to create a basic web app that has an HTML form on the root landing page, and then after submission, run a postgresql query with the desired input and redirect the user to a page with a generated matplotlib chart of their input. In my main function, I have the following:
#app.route('/', methods=['POST'])
def main():
return render_template("main.html")
So let's say I have my main html file being rendered by the flask app. I have another route below:
#app.route('/query', methods=['POST'])
def queryPage():
# code to execute query with information
# passed from the main.html template
# then generate chart via matplotlib via returned information
return render_template("query.html")
I'm confused as to how to get my input from the form in main.html to send information back to the application for rendering at the /query endpoint. If someone could elaborate on this, I'd appreciate it. Front end is not my strong suit. Thanks!
You need a form on main.html... maybe like this (note the form action):
<form action = /query method="POST">
<label for="username">USERNAME:</label>
<input type="text" name="username" id="username" size="15">
<input type="submit" name="submit" id="submit"/>
</form>
When that form gets sent (after a user clicks a button lets say), the route in your flask code that matches the action (/query in this case) will get called and execute. Also the name= variables in any of your form elements will be available in your request on the back end (I'm using the variable username as an example). You can get them like this: request.form['username']. Other form variables (like a check box) will be slightly different.
Anyway in your case you need a /query action in your html somewhere in main.html.... It could be called by a button or timed javascript etc...
When this /query action is called on your main.html, you need to
return render_template('query.html, username=username)
and then the username variable will be available on the query.html page.
Keep in mind I only passed a single variable. You can pass a multiple variables, lists, dictionaries etc...
Also keep in mind any variable that you return to query.html can be made extremely dynamic using Jinja templating. You can loop through lists and print different html tags etc and use logic within your html... possible depending on what the values are that get returned to the page.
If I understand your question correctly then you are having difficulty passing the form information from your main function to the separate queryPage function for rendering. This can easily be achieved by providing the values you wish to pass as keyword arguments to the url_for function. These can then be retrieved from request.args within the queryPage function. Given the fact that you are returning query.html from this function and not an image, I assume that you are intending on displaying your chart within an img tag in query.html. In this case you will need another view function to generate and return the image itself. You may also need to disable browser caching for this endpoint to prevent browsers treating your dynamic image as if it were a static image https://stackoverflow.com/a/2068407/10548137.
#app.route('/', methods=['GET', 'POST'])
def main():
form = MyForm(request.form)
if request.method == "POST" and form.validate():
return redirect(url_for("queryPage", **form.data))
return render_template("main.html", form=form)
#app.route('/query', methods=['GET'])
def queryPage():
arguments = request.args.to_dict()
image_url = url_for("make_chart", **arguments)
return render_template("query.html", image_url=image_url)
#app.route('/make_chart', methods=['GET'])
def make_chart():
arguments = request.args.to_dict()
# perform postgres query here using arguments
# generate matplotlib chart here using query results
# ? save chart in BytesIO buffer in png format
response = send_file(file_pointer, mimetype="image/png")
# just return response here if don't need to alter headers
response = make_response(response)
response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
response.headers["Pragma"] = "no-cache"
response.headers["Expires"] = "0"
return response
Need to access URL by name at model, can't just hardcode it. Need it for error message for a new object creating. Any suggestions?
Update: Just need to put url to error message, not reverse
Your question is not totally clear, but I think you are asking about the reverse function.
You can define get_absolute_url method in your model and than access it in other model's methods. Check https://docs.djangoproject.com/en/2.1/ref/models/instances/#get-absolute-url
I suggest you use a template tag. You can build one for your model and avoid polluting the model about stuff not related to the domain level and keep the presentation level to the template.
Check the docs here on how add a templatetags your app.: https://docs.djangoproject.com/en/2.1/howto/custom-template-tags/
Here a snippet of code to use as starting point for your url generation
from django import template
register = template.Library()
#register.simple_tag(takes_context=True)
def url_for_object(context, object):
# you have both the context and the object available to
# generate your url here
url = ....
return url
In your template use
{% url_for_object my_object %}
If I'm making a blog site and I want to set up routing such that
#app.route('/<username>/<postname>', methods=['GET'])
routes to the post with name 'postname' of the user with name 'username', how do I get the html to recognize this? I've been trying to do something like
<a href={{ url_for('/', username=user.name, postname=post.name) }}>{{post.name}}</a>
I'm also trying to reconcile this with Flask understanding special keywords /login or /about so that it checks if the user is trying to access those first. How can I implement those checks?
The first argument to url_for in your template should be the name of the view function you decorated:
#app.route('/<username>/<postname>', methods=['GET'])
def view_user_post(username, postname):
^^^^^^^^^^^^^^
Now, you can write this in your template:
{{ url_for('view_user_post', username=user.name, postname=post.name) }}
This lets you change the URL in the route without having to update it elsewhere in your codebase.