2016-12-06 48 views
0

私は小さなオンラインプラントデータベースを構築しようとしており、検索エンジンを組み込みたいと考えています。私はFlaskでアプリケーションを構築していますが、アプリケーションはSQLAlchemyとpymysqlを使用してMySQLデータベースに接続しています。私はFlask-WhooshAlchemyを手にしていて、これまで運がない。私が望むのは、ユーザーが特定のプラントを検索してプラント情報ページに行くか、類似の種の結果を返すかどうかを検索することです。たとえば、「Carex utriculata」を検索する場合は、「Carex utriculata」の種情報ページに直接表示されます。しかし、彼らが 'Carex'を検索した場合、彼らは類似の種をすべて列挙した結果ページを得ることになるので、 'Carex aquatilis' 'Carex keloggii''Carex utriculata'のようなリストがあるかもしれません。Flask - SQLAlchemy全文検索

これまでの試みでは、検索が試行されているように見えますが、結果は検索に入力されたものだけでなく、データベース内のすべての植物を表示します。そして、私は検索を正確に一致させるためには、検索を動作させることに悩まされていたので、検索を個々の工場のページにまっすぐに行かせようと試みたことさえありませんでした。私はPython 3.5で作業しています。ここに私のコードです。

のinitの.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() 

が、私はあなたがそれが大文字小文字を区別しないようにしたいと仮定します。そうでない場合は、このクエリで置き換えてください。

私はあなたのルートは、種のページのためのように見えますが、把握するのは難しいすべきではないかわからないので、私はまた、リダイレクトを空白のままに。

EDITは、関数定義を変更し、マイナーチェンジはそうのように、テンプレートに追加する必要があります

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

感謝お返事。私はそれが問題の解決に近づいていると思う。しかし、今は私にエラーを投げている。 UnboundLocalError:ローカル変数 'results'が割り当て前に参照されています。私はエラーに見て、他の人が、私は結果がグローバルにしようとしているような推奨フィックスのいくつかを試してみましたtimes..butいくつか尋ねてきたこれに多くのことを実行し、他の同じ質問をすることを憎むしていることを発見しました。試した修正はうまくいきません。このエラーを修正するための提案はありますか? – DazedAndConfusedNewby

+0

@DazedAndConfusedNewbyああ、私は参照してください。 –

+0

@DazedAndConfusedNewby実際には、空の結果変数を受け入れるようにテンプレートを編集しなければならない場合もあります。私はそれに応じて答えを編集します。 –