Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

search function (query in Flask, SQLAlchemy)

I'm new to programming and Flask and I am stuck on this problem.

I am trying to implement a search function in a web application that will take data from a form and compare it to a value in the database and list results.

This is what I have so far:

views.py

@app.route('/search', methods=['GET', 'POST'])
def search():
    searchForm = searchForm()
    courses = models.Course.query.order_by(models.Course.name).all()
    if searchForm.validate_on_submit():
        for i in courses:
            if searchForm.courseName.data == i.name:
              searchResult = models.Course.filter(Course.name.like('%searchForm.courseName.data%'))
    return render_template('courselist.html', courses = courses, searchResult = searchResult)

form.py

class searchForm(Form):
    courseName = StringField('Search course', validators=[DataRequired(), Length(max=60)])

database models.py

class Course(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(40), unique=True)
    courseCode = db.Column(db.String(10), unique=True)
    duration = db.Column(db.Integer)
    maxStudents = db.Column(db.Integer)
    startDate = db.Column(db.DateTime)
    prerequisites = db.Column(db.String(500))
    trainerID = db.Column(db.Integer, db.ForeignKey('trainer.id'))
    venueID = db.Column(db.Integer, db.ForeignKey('venue.id'))

    sessions = db.relationship('Session', backref='course', lazy='dynamic')
    bookings = db.relationship('Booking', backref='course', lazy='dynamic')

html file

{% extends "index.html" %}
{% block content %}
<h3>Courses:</h3>
<ul>
    {% for course in courses %}
    <li>
    <h4><a href="/viewcourse?id={{course.id}}">{{course.name}}</a>
    <a class="btn btn-success" href="/editcourse?id={{course.id}}">Book</a>
    <a class="btn btn-info" href="/editcourse?id={{course.id}}">Edit</a>
    <a class="btn btn-danger" href="/deletecourse?id={{course.id}}">Delete</a></h4>
    </li>
    {% endfor %}
</ul>
{% endblock %}

I think the general logic is right but I need some help adjusting it.

like image 610
C. Mauro Avatar asked Mar 03 '17 12:03

C. Mauro


People also ask

What is flask-SQLAlchemy?

Instead, SQLAlchemy, the Python Toolkit is a powerful OR Mapper, which provides application developers with the full functionality and flexibility of SQL. Flask-SQLAlchemy is a Flask extension that adds support for SQLAlchemy to the Flask application.

How do I filter a SELECT query in flask-SQLAlchemy?

For this purpose Flask-SQLAlchemy provides a query attribute on your Model class. When you access it you will get back a new query object over all records. You can then use methods like filter () to filter the records before you fire the select with all () or first (). If you want to go by primary key you can also use get ().

How to query in SQLAlchemy?

Here is a collection of queries showing other scenarios. 1. Query one table To query just one table you can also use the object directly rather than db.session. Given below example SQL. It will equate to this in SQLalchemy.

How do I return a 404 error in flask-SQLAlchemy?

If you write a Flask view function it’s often very handy to return a 404 error for missing entries. Because this is a very common idiom, Flask-SQLAlchemy provides a helper for this exact purpose. Instead of get()one can use get_or_404()and instead of first()first_or_404(). This will raise 404 errors instead of returning None:


2 Answers

Your logic in views.py seems a bit off. You're retrieving all Course objects from the database and looping through them. Then you check if the course name exactly matches the search input - and if so, try to find matching courses. I think it would be better constructed like this:

@app.route('/search', methods=['GET', 'POST'])
def search():
    searchForm = searchForm()
    courses = models.Course.query

    if searchForm.validate_on_submit():
        courses = courses.filter(models.Course.name.like('%' + searchForm.courseName.data + '%'))

    courses = courses.order_by(models.Course.name).all()

    return render_template('courselist.html', courses = courses)
like image 124
Matt Healy Avatar answered Sep 18 '22 18:09

Matt Healy


This is this is the simplest answer :

@app.route("/search", methods=['GET'])
def search():
    query = request.args.get("query") # here query will be the search inputs name
    allVideos = Videos.query.filter(Videos.title.like("%"+query+"%")).all()
    return render_template("search.html", query=query, allVideos=allVideos)
like image 22
Lakshyaraj Dash Avatar answered Sep 17 '22 18:09

Lakshyaraj Dash