2016-12-06 145 views
0

我正在尝试建立一个小型在线工厂数据库,并且希望合并一个搜索引擎。我使用Flask构建我的应用程序,并使用SQLAlchemy和pymysql将应用程序连接到MySQL数据库。我一直在摆弄Flask-WhooshAlchemy,到目前为止我没有运气。我想要的是搜索,如果用户搜索特定的工厂,它将会转到工厂信息页面或返回类似物种的结果。例如,如果他们要搜索'Carex utriculata',它会直接将它们带到'Carex utriculata'的物种信息页面。但是如果他们搜索'Carex',他们会得到一个列出所有类似物种的结果页面,因此可能有一个像'Carex aquatilis''Carex keloggii''Carex utriculata'的列表。烧瓶 - SQLAlchemy全文搜索

在我到目前为止的尝试中,似乎尝试了搜索,但结果显示了我数据库中的所有植物,而不仅仅是输入搜索的内容。如果搜索与搜索完全匹配,我甚至没有尝试过让搜索直接进入单个工厂的页面,因为我一直坚持让搜索工作。我正在使用Python 3.5。这是我的代码。

初始化的.py

import pymysql.cursors 
from flask import Flask 
from flask_sqlalchemy import SQLAlchemy 
import flask_whooshalchemy as whooshalchemy 


app = Flask(__name__) 


app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:[email protected]/restorationplantdb' 
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True 
app.config['WHOOSE_BASE'] = 'results' 


db = SQLAlchemy(app) 

class SPInfo(db.Model): 
    __tablename__ = 'speciesinfo' 
    __searchable__ = ['NRCS_Species', 'NRCS_CommonName'] 
    speciesinfo_id = db.Column(db.Integer,primary_key=True) 
    ID = db.Column(db.Integer) 
    MTNHP_Species = db.Column(db.String(45)) 
    NRCS_Species = db.Column(db.String(45)) 
    NRCS_CommonName = db.Column(db.String(45)) 
    Synonyms = db.Column(db.Text) 
    Sp_Stratum = db.Column(db.String(12)) 
    Origin = db.Column(db.String(25)) 
    Duration = db.Column(db.String(25)) 
    Habitat = db.Column(db.Text) 
    Elevation = db.Column(db.Text) 


whooshalchemy.whoosh_index(app, SPInfo) 

import RestorationPlantDB.views 

views.py

from flask import render_template, url_for, redirect, session, request 
from datetime import datetime 
from RestorationPlantDB import app 
from RestorationPlantDB import db 
from RestorationPlantDB import SPInfo 



@app.route('/search', methods = ['GET','POST']) 
def search(): 
    results = SPInfo.query.all() 
    return render_template('search.html', results=results) 

@app.route('/results') 
def results(): 
    results = SPInfo.query.whoosh_search(request.args.get('query')).all() 
    return render_template('search.html', results=results) 

search.html

{% extends "layout.html" %} 

{% block content %} 


{% for result in results %} 
<p>{{ result.NRCS_Species }} - {{ result.NRCS_CommonName }}</p> 
{% endfor %} 



<div class="col-sm-3 col-sm-offset-1 blog sidebar"> 
    <div class="sidebar-module sidebar-module-insert"> 
     <h4>Search</h4> 
     <form class="form-inline" method="GET" action="search"> 
      <div class="form-group"> 
       <label for="query">Name</label> 
       <input type="text" class="form-control" name="query" id="query" /> 
      </div> 
      <button type="submit" class="btn btn-primary">Search</button> 
     </form> 
    </div> 
</div> 


{% endblock %} 

回答

0

所有你正在做的是查询一切,这就是为什么你一切。您正在过滤/results下的查询,但表单不会去那里。您可以轻松地做到这一点:

@app.route('/search', methods = ['GET','POST']) 
def search(results=None): 
    if request.method == 'POST': 
     results = SPInfo.query.whoosh_search(request.form.get('query')).all() 
    return render_template('search.html', results=results) 

并完全删除/results。接下来,你会想实现重定向到完全匹配。我想补充一点到上面的代码为:

from sqlalchemy import func 

@app.route('/search', methods = ['GET','POST']) 
def search(results=None): 
    if request.method == 'POST': 
     keywords = request.form.get('query') 
     unique_result = SPInfo.query.filter(func.lower(SPInfo.NRCS_Species) == func.lower(keywords)).first() or SPInfo.query.filter(func.lower(SPInfo.NRCS_CommonName) == func.lower(keywords)).first() 
     if unique_result: 
      #insert return redirect() to specific page using unique_result here 
     results = SPInfo.query.whoosh_search(keywords).all() 
    return render_template('search.html', results=results) 

一般情况下我刚刚做了:

unique_result = SPInfo.query.filter_by(NRCS_Species=keywords).first() or SPInfo.query.filter_by(NRCS_CommonName=keywords).first() 

,但我假设你希望它是不区分大小写。如果你不这样做,用这个替换查询。

我也离开了重定向空白,因为我不知道你的路线看起来像物种页面,但它不应该很难弄清楚。

编辑

改变了函数定义,需要一个小的改动将被添加到模板,像这样:

{% if results %} 
    {% for result in results %} 
     <p>{{ result.NRCS_Species }} - {{ result.NRCS_CommonName }}</p> 
    {% endfor %} 
{% endif %} 
+0

感谢您的回复。我认为这更接近解决这个问题。但现在它向我抛出一个错误。 UnboundLocalError:赋值之前引用的局部变量“结果”。我查看了这个错误,发现其他人已经遇到了很多问题,并且讨厌提出同样的问题,其他人也问了好几次。但是我尝试了一些建议的修复方法,比如试图让结果成为全局的。我尝试的修复似乎不起作用。任何建议来解决这个错误? – DazedAndConfusedNewby

+0

@DazedAndConfusedNewby哦,我明白了。所有你需要做的就是用'def search(results = None)替换'def search():'' –

+0

@DazedAndConfusedNewby实际上,你可能还需要编辑模板来接受一个空的结果变量。我会相应地编辑答案。 –