从python flask中的mysql popluate组合框值

时间:2018-03-29 08:47:17

标签: python python-3.x sqlalchemy flask-wtforms

我是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)

2 个答案:

答案 0 :(得分:0)

Flask是一个静态的网页渲染器,这意味着当用户加载一个路径时,比如'/ my_page'将执行python函数,它将生成一些变量然后传递给网页,可以是由jinja2模板语言渲染。此时页面已创建。

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

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

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

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

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

一个非常好的反应式Javascript库,使上面的可访问性是Vue.js。

如果上述内容对于您要实现的目标而言过于复杂,一种解决方案就是打破4个组合框。在每个组合框之后有一个“下一个”按钮,它是指向另一个烧瓶路径的超链接,所以你基本上有4个页面,每个页面都是另一个页面的扩展名。这将允许python执行大部分编码,但是当刻录机重新渲染时,您的前端将不断刷新新页面。

答案 1 :(得分:0)

下面是sol:

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))