0

I am ordering the query result using time but I want to give the user the ability to choose the way he wants to order data lets say he wants to use alphabetical order or he wants to order with ascending or descending order I want to know how to that in flask, sorry for my bad English

this is my code

@routes.route('/posts')
def show_posts():
    page=request.args.get('page',1,type=int)
    posts=Posts.query.order_by(Posts.timestamp.desc).paginate(page,per_page=10)
    return render_template('routes/show_posts.html',posts=posts)
4
  • for that You will need to have a form, that collects this data of how to order the posts Commented Jul 19, 2021 at 0:36
  • I know I need a form I want to know how to implement it like other websites that have a select field when you choose the way to order data immediately applies Commented Jul 19, 2021 at 1:09
  • uses urls like /posts?order=alphabetical&ascending=True and then get order and ascending to use it in database Commented Jul 19, 2021 at 2:59
  • 1
    if you want to immediately applies (without reloading page) then you have to use JavaScript for this. You can use some library which can change order using data existing in HTML or you may need code which sends AJAX request to Flask to get data in new order or with new filters. Commented Jul 19, 2021 at 3:01

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

4 Comments

you could add description which elements are important - like /posts/filter_by/<string:key>
@furas added some explanation
you added more then I expected :) I upvoted it. Now OP has to decide if it is good answer for his problem.
@furas well actually in my opinion I could have explained a bit more in detail (at least the parts that I knew that much about) but ok, thank You for the upvote
0

first thing first Matiiss your answer is very good thanks for the help, now I have found another way it has some similarities to Matiiss answer i want to share it so if anyone found this question now you have two answers to choose from.

@routes.route('/posts')
def show_posts():
    posts= Posts.query.order_by(Posts.name.desc()).all()
    filter_rule = request.args.get('filter')
    if filter_rule == 'A-Z':
        posts= Posts.query.order_by(Posts.name).all()
    return render_template('posts.html',posts=posts)

HTML part

<div class="row">
        <div class="col-md-3">
            <div class="nav nav-pills flex-column" role="tablist" aria-orientation="vertical">
                <a class="nav-item nav-link"
                   href="{{ url_for('.show_posts', filter='A-Z') }}">
                    A-Z
                </a>
                <a class="nav-item nav-link"
                   href="{{ url_for('.show_posts', filter='Z-A') }}">
                    Z-A
                </a>
            </div>
        </div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.