ok, so this is my first flask answer (I only yesterday finished tutorials):
EDIT/INFO: at the end I didn't use any forms to accomplish this, just simple routes, but forms could be used too, this just seemed a bit more simple (more because I couldn't figure out how to use those forms for this :))
EDIT2/INFO: also I don't think for this particular code there is any need for that methods argument in decorators so that could probably be removed for this specific code
the main file (it contains everything because that was easier than to show each module I would have used)
from flask import Flask, render_template, url_for
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
db = SQLAlchemy(app)
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100), nullable=False)
content = db.Column(db.Text, nullable=False)
@app.route('/posts/filter_by/<string:key>')
@app.route('/posts', methods=['GET', 'POST'])
@app.route('/')
def all_posts(key=None):
posts = Post.query.order_by(Post.title.asc()).all()
if key == 'ZA':
posts = Post.query.order_by(Post.title.desc()).all()
return render_template('posts.html', posts=posts)
if __name__ == '__main__':
app.run(debug=True)
and here is the template (uses bootstrap stuff):
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<title>Hello, world!</title>
</head>
<body>
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle"
type="button" id="dropdownMenu1" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false">
Sort by
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenu1">
<a class="dropdown-item" href="{{ url_for('all_posts', key='AZ') }}">A-Z</a>
<a class="dropdown-item" href="{{ url_for('all_posts', key='ZA') }}">Z-A</a>
</div>
</div>
{% for post in posts %}
<div class="card">
<div class="card-body">
<h4 class="card-title">{{ post.title }}</h4>
<p class="card-text">{{ post.content }}</p>
</div>
</div>
{% endfor %}
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>
So the first thing (top-down):
import all that is needed
then initialize the Flask and SQLAlchemy classes and also config the app to the database
Create the post model for storing posts and stuff (that I don't exactly know)
So then comes the main part - the route.
So first of I create a route with a variable:
@app.route('/posts/filter_by/<string:key>')
this will allow to request this URL and be able to get additional information (from that variable) that will help with handling the response
then add more routes so that the url looks cleaner and that is pretty much the only reason (as far as I know)
then define the function:
name it what You feel like but You have to pass the variable as an argument and since multiple routes are used and probably for other reasons too set a default value for that argument so that it is not necessary to be provided
then using simple if statements and using that variable handle how posts are ordered
then return the template including those posts in that order
Now about the template
First of it uses bootstrap stuff and I got the most code from there (just copy pasted from their website) or here which is a nice cheatsheet.
So I copied the dropdown menu from that cheatsheet and just changed some values, most notably the href attribute:
Those I replaced with url_for functions and passed the variable too as You can see so that the request sent is with that variable that will allow to handle how posts are ordered
Hope all is clear, if You have any more questions, ask them.
/posts?order=alphabetical&ascending=Trueand then getorderandascendingto use it in database