Вопрос

Below is an example of the page I'm making. In this example, I have two select fields that are used to filter the results on the right side when the submit button is pressed.

The way I solved the problem involved using if-elif-else, but if I have more filters my code will be difficult to manage. In this case I have 2 filters, that means 4 distints queries to manage, if I had 4 filters that would mean 16 different queries.

Can you suggest me a better way of doing it, instead of my approach ?

enter image description here

Essentials part of my code:

models

class StandardName(db.Model):
    __tablename__ = 'std_names'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)
    standards = db.relationship('Standard', backref='stdname', lazy='dynamic')


class Standard(db.Model):
    __tablename__ = 'standards'
    id = db.Column(db.Integer, primary_key=True)
    stdname_id = db.Column(db.Integer, db.ForeignKey('std_names.id'))
    group = db.Column(db.String)

form

class StandardForm(Form):
    standard = SelectField("Select the standard: ", 
                                choices=[("All","All"),("mamp","mamp"), ("est","est"])
    group = SelectField("Select the group: ", 
                            choices=[('All','All'),('1','1'),('2','2'),('3','3')])
    submit = SubmitField('Submit')

view

The view function will show the query results according to the Select Field. In this case:

  • if the user chooses "All" in both standard and groups fields, the view will execute Standard.query.

  • If the user choose "All" only in the standard field, the view will filter only the group column

  • If the user choose "All" only in the group field, the view will filter only the standard column

  • Choosing another option in thoses field will be used to filter the query.

    @app.route("/", methods=['GET', 'POST'])
    def index():
        form = StandardForm()
        if form.standard.data == "All" and form.group.data == "All":
            q = Standard.query
        elif form.standard.data == "All":
            q = Standard.query.filter(
                Standard.group == form.group.data)
        elif form.group.data == "All":
            q = Standard.query.filter(
                Standard.stdname.has(name=form.standard.data))
        else:
            q = Standard.query.filter(
                Standard.stdname.has(name=form.standard.data),
                Standard.group == form.group.data)
    
        return render_template(
            'index.html',
            form=form,
            standards=q.all())
    
Это было полезно?

Решение

I came up with a more generic form of solving this problem.

@app.route("/", methods=['GET', 'POST'])
def index():
    form = StandardForm()

    std = form.data.get('standard')
    group = form.data.get('group')

    q = Standard.query
    for fieldname, value in form.data.items():
        if fieldname == 'standard' and value != "All":
            q = q.filter(Standard.stdname.has(name=std))
        elif fieldname == 'group' and value != "All":
            q = q.filter(Standard.group == group)

    return render_template(
        'index.html',
        form=form,
        standards=q.all())
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top