从 python 烧瓶中的 mysql 填充组合框值

popluate combobox value from mysql in python flask

我是 codding 和 flask 的新手,我想知道如何根据以前的组合框检索组合框值。

我按照教程成功地从数据库中检索了第一个组合框值。

https://www.youtube.com/watch?v=b9W2ul2VRRc&t=761s

现在基于该值我想检索第二个值。您能否检查我的代码并建议我如何放置过滤条件

假设我必须先组合框 customer_name,然后再组合框 instance_name。
如果我选择 customer =tcs 那么相应的 instance_name 必须显示在下一个组合框中,例如 instance_name = tcs_test_33i

class custdetail(db.Model):
    cust_id = db.Column(db.Integer, primary_key=True)
    customer = db.Column(db.String(50))
    instance_name = db.Column(db.String(50)) 


def Customer_query():
    return custdetail.query

def Customer_query_env():
    return custdetail.query#.filter(custdetail.customer == customer) 


class CustomerForm(FlaskForm):
    opts = QuerySelectField(query_factory=Customer_query, allow_blank=False, get_label='customer')

class CustomerEnv(FlaskForm):
    opts1 = QuerySelectField(query_factory=Customer_query_env, allow_blank=False, get_label='instance_name')


@app.route('/runpage/', methods=['GET', 'POST'])
def index():
    form = CustomerForm()
    form1 = CustomerEnv()

    form.opts.query = custdetail.query.filter(custdetail.cust_id > 0)
    #form1.opts1.query = custdetail.query.filter(custdetail.customer == format(form.opts.data))


    if form.validate_on_submit():
        return '<html><h1>{}</h1></html>'.format(form.opts.data)

    if form1.validate_on_submit():
        return '<html><h1>{}</h1></html>'.format(form1.opts1.data)

    return render_template('runpage.html', form=form, form1=form1)

if __name__ == '__main__':
    app.run(debug=True)

Flask 的基本形式是网页的静态渲染器,这意味着当用户加载路由时,说'/my_page' python 函数将被执行,它会生成一些变量然后传递到网页并可以通过 jinja2 模板语言呈现。此时页面已创建。

如果您的用户随后更改了页面上的某些内容并且您需要更新某些内容,那么这称为前端动态或反应性。在这种情况下,当您的用户更改表单元素时,这意味着必须更新其他表单元素。

通常有两种方法可以将其与 Flask 集成,但都需要用户端前端 Javascript,您无法真正避免这种情况。

方法1:预先计算所有可能的组合并将所有值传递给渲染模板并将它们存储在javascript中,并在表单更改时动态更新您需要的那些。

方法 2:在 flask 中构建一个 API 函数,当表单值发生变化时,您的 javascript 可以访问它,它将从 python 中获取值(通过 SQL) 获取,然后 javascript 可以更新用户浏览器中的表单。

方法一比较简单,当python所有组合的处理速度很快时,使用它来处理小组合,但是当需要大量处理时,这种方法会大大增加页面加载的开销(大多数这将是多余的)。方法 2 更有效,应该在需要的处理更复杂或组合很大时使用(即你有很多用户并且不能在渲染中预填充所有)

一个非常好的响应式 Javascript 库使上述内容易于访问 Vue.js。

如果以上内容对于您要实现的目标来说过于复杂,一种解决方案是将 4 个组合框分开。每个组合框后都有一个 'next' 按钮,它是指向另一个 flask 路由的超链接,因此您基本上有 4 个页面,每个页面都是另一个页面的扩展。这将允许 python 完成大部分编码,但是当 flask re-renders.

时,您的前端将不断刷新新页面

下面是解决方案:

runpage.html 文件:

<html>
<head>
    <title>Form</title>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"> </script>
    <script type = "text/javascript" 
         src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script charset="utf-8" type="text/javascript">
    $(function() {
        var dropdown = {
            customer: $('#select_customer'),
            product: $('#select_product')
        };

        // function to call XHR and update product dropdown
        function updateproduct() {
            var customer = dropdown.customer.val();
            dropdown.product.attr('disabled', 'disabled');
            console.log(customer);

            if (customer.length) {
                dropdown.product.empty();
                $.getJSON("{{ url_for('productChange') }}", {customer: customer}, function(data) {
                    console.log(data);
                    data.forEach(function(item) {
                        dropdown.product.append(
                            $('<option>', {
                                value: item.vals,
                                text: item.vals
                            })
                        );
                    });
                    dropdown.product.removeAttr('disabled');
                });
            }
        }

        // event listener to customer dropdown change
        dropdown.customer.on('change', function() {
            updateproduct();
        });

    });
</script>
</head>
<body>
    <form action="/runpage/" method="POST" >
        {{ form.customer}}
        {{ form.product }}
        <input type="submit">
    </form>
</body>
</html>

--dbconnect.py

import MySQLdb
def connection():
    conn = MySQLdb.connect(host="localhost.localhost",
                           user = "usrname",
                           passwd = "pwd123",
                           db = "pythonp")
    c = conn.cursor()
    return c, conn   

app.py 文件:

from flask import *
import os
from dbconnect import connection
from flask import Flask, render_template, flash, request, url_for, redirect, session,Response
from wtforms import Form, BooleanField, TextField, PasswordField, validators,SelectField
from passlib.hash import sha256_crypt
from MySQLdb import escape_string as thwart
#from flask_sqlalchemy import SQLAlchemy 
from flask_wtf import FlaskForm 
from wtforms_sqlalchemy.fields import QuerySelectField
from urllib.request import *
from flask import json
import gc 

app = Flask(__name__)
app.secret_key = 'my unobvious secret key'



class runpageForm(Form):
    customer = SelectField('Select your customer Name', choices=[], id='select_customer')
    product = SelectField('Select your product Name', choices=[], id='select_product')

@app.route('/runpage/', methods=['GET', 'POST'])
def runpage():

    try:
      form = runpageForm()
      if request.method == "POST" :
            # loading values in SelectFields on page load

            for row in fetch_customer('custdetail', 'customer'):
                  customer = str(row[0])
                  form.customer.choices += [(customer, customer )]   ;
                  #value_customerqq = dict(form.customer.choices).get(form.customer.data)

      return render_template("runpage.html", form=form)
    except Exception as e:
        error = "Invalid credentialsw, try again."
        return(str(e))


@app.route('/productChange/', methods=['GET', 'POST'])
def productChange():
    try:
      form = runpageForm()
      if request.method == "GET":
               customer = request.args.get('customer')
               print(customer)
               c, conn = connection()
               c.execute("SELECT product FROM custdetail WHERE customer = %s", [customer])
               product = c.fetchall()
               print(product)

               data = [{"vals": x[0]} for x in product]
               print ("hello tript")
               print (data)
               c.close()

      return jsonify(data)

    except Exception as e:
        error = "Invalid customer name, try again."
        return(str(e))