Flask 使用一个;短语搜索“;瓶内管理

Flask 使用一个;短语搜索“;瓶内管理,flask,flask-admin,Flask,Flask Admin,我正在使用Flask Admin,我对此非常满意 显示可用于搜索预定义字段的多个选项。我希望允许我的用户使用引号进行搜索,例如,在: "some phrase of which the order should be intact" 如何使用Flask Admin执行此操作?在Flask Admin 1.3.0中,您可以覆盖Admin view类中的“应用”搜索方法。请参阅下面非常简单的代码示例-主要取自Flask Admin sqla example app.py 基本上,您希望为列\u可搜

我正在使用Flask Admin,我对此非常满意

显示可用于搜索预定义字段的多个选项。我希望允许我的用户使用引号进行搜索,例如,在:

"some phrase of which the order should be intact"

如何使用Flask Admin执行此操作?

在Flask Admin 1.3.0中,您可以覆盖Admin view类中的“应用”搜索方法。请参阅下面非常简单的代码示例-主要取自Flask Admin sqla example app.py

基本上,您希望为列\u可搜索\u列表中的列生成一个类似于%Your Phrase Here%的SQL。_apply_search的标准行为是在空格上拆分搜索输入文本,并为结果数组中的每个词生成类似SQL的片段

相反,您可以使用正则表达式查看是否输入了带引号的字符串,提取引号中的短语,创建适当的类似SQL的片段,然后将其传递给生成查询的代码

您还可以执行类似于实现短语过滤的操作—请参阅下面代码中的类FilterPhrase,以及它在列过滤器列表定义中的使用方式

对于更复杂的短语搜索,您可以使用Postgres内置的短语搜索功能(可能结合)甚至

#编码:utf-8
__作者:保罗
从烧瓶进口烧瓶
从flask.ext.sqlalchemy导入sqlalchemy
从sqlalchemy导入或_
从flask.ext.admin导入管理
从flask.ext.admin.contrib.sqla导入模型视图
从flask.ext.admin.babel导入lazy\u gettext
从flask.ext.admin.contrib.sqla.filters导入BaseSQLAFilter
进口稀土
app=烧瓶(名称)
app.config['SQLALCHEMY\u DATABASE\u URI']='sqlite://:memory:'
app.config['SQLALCHEMY_ECHO']=True
db=SQLAlchemy(应用程序)
@应用程序路径(“/”)
def index():
返回“”
班级职位(db.Model):
id=db.Column(db.Integer,主键=True)
title=db.Column(db.String(255))
content=db.Column(db.Text,null=False)
def ___; unicode(自):
返回自己的标题
类过滤器短语(BaseSQLAFilter):
def apply(自我、查询、值、别名=无):
stmt=“%{phrase}%.”格式(phrase=value)
return query.filter(self.get_列(别名).ilike(stmt))
def操作(自):
返回lazy\u gettext('短语')
类PostAdmin(模型视图):
列可搜索列表=['title','content']
列过滤器=(
过滤措辞(Post.title,“title”),
过滤短语(Post.content,“content”),
)
定义应用搜索(自我、查询、计数查询、联接、计数联接、搜索):
短语=re.findall(r'([^“]*)”,搜索)
如果len(短语)==0:
返回super(PostAdmin,self)。\应用\搜索(查询,计数\查询,联接,计数\联接,搜索)
stmt=“%{phrase}%.”格式(phrase=phrases[0])
#下面的代码直接取自基本应用搜索
筛选器_stmt=[]
计数\u过滤器\u stmt=[]
对于字段,在self.\u search\u字段中的路径:
查询,连接,别名=self.\u应用\u路径\u连接(查询,连接,路径,内部\u连接=False)
count\u alias=None
如果count\u查询不是None:
count\u查询,count\u连接,count\u别名=self.\u应用\u路径\u连接(count\u查询,
伯爵加入,
路径
内部(连接=错误)
column=字段,如果别名为None-else getattr(别名,field.key)
过滤器\u stmt.append(column.ilike(stmt))
如果count\u filter\u stmt不是无:
如果count\u别名为None-else,则column=字段getattr(count\u别名,field.key)
count\u filter\u stmt.append(column.ilike(stmt))
query=query.filter(或(*filter\u stmt))
如果count\u查询不是None:
count\u query=count\u query.filter(或(*count\u filter\u stmt))
返回查询,计数查询,联接,计数联接
#创建管理员
admin=admin(应用程序,name='Phrase search')
admin.add_视图(PostAdmin(model=Post,session=db.session,category='Blog',name='Posts'))
def build_db():
样本职位=[
{
“标题”:“博诺拉姆和马洛拉姆有限公司-第一部分”,
“内容”:Lorem ipsum Door sit amet,为精英服务,为临时雇员提供服务”
},
{
‘标题’:“博诺勒姆和马洛勒姆-第二部分”,
‘内容’:“所有人都有一个明显的错误,这是因为他们在积累财富。”
},
{
‘标题’:“博诺勒姆和马洛勒姆有限公司——第三部分”,
‘内容’:“在维罗eos和accusamus和iusto Dignessimos ducimus qui blanditiis praesentium”
}
]
db.drop_all()
db.create_all()
对于示例_帖子中的行:
post=post(**行)
db.session.add(post)
db.session.commit()
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
build_db()
app.run()

因为你似乎是一名flask管理员:为了以防万一你知道答案,我从……开始悬赏。)
# coding: utf-8
__author__ = 'Paul'

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
from sqlalchemy import or_
from flask.ext.admin import Admin
from flask.ext.admin.contrib.sqla import ModelView
from flask.ext.admin.babel import lazy_gettext
from flask.ext.admin.contrib.sqla.filters import BaseSQLAFilter
import re

app = Flask(__name__)

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:'
app.config['SQLALCHEMY_ECHO'] = True
db = SQLAlchemy(app)


@app.route('/')
def index():
    return '<a href="/admin/">Click me to get to Admin!</a>'


class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(255))
    content = db.Column(db.Text, nullable=False)

    def __unicode__(self):
        return self.title


class FilterPhrase(BaseSQLAFilter):
    def apply(self, query, value, alias=None):
        stmt = "%{phrase}%".format(phrase=value)
        return query.filter(self.get_column(alias).ilike(stmt))

    def operation(self):
        return lazy_gettext('phrase')


class PostAdmin(ModelView):
    column_searchable_list = ['title', 'content']

    column_filters = (
        FilterPhrase(Post.title, "Title"),
        FilterPhrase(Post.content, "Content"),
    )

    def _apply_search(self, query, count_query, joins, count_joins, search):

        phrases = re.findall(r'"([^"]*)"', search)

        if len(phrases) == 0:
            return super(PostAdmin, self)._apply_search(query, count_query, joins, count_joins, search)

        stmt = "%{phrase}%".format(phrase=phrases[0])

        # The code below is taken directly from the base _apply_search
        filter_stmt = []
        count_filter_stmt = []

        for field, path in self._search_fields:
            query, joins, alias = self._apply_path_joins(query, joins, path, inner_join=False)

            count_alias = None

            if count_query is not None:
                count_query, count_joins, count_alias = self._apply_path_joins(count_query,
                                                                               count_joins,
                                                                               path,
                                                                               inner_join=False)

            column = field if alias is None else getattr(alias, field.key)
            filter_stmt.append(column.ilike(stmt))

            if count_filter_stmt is not None:
                column = field if count_alias is None else getattr(count_alias, field.key)
                count_filter_stmt.append(column.ilike(stmt))

        query = query.filter(or_(*filter_stmt))

        if count_query is not None:
            count_query = count_query.filter(or_(*count_filter_stmt))

        return query, count_query, joins, count_joins


# Create admin
admin = Admin(app, name='Phrase Searching')
admin.add_view(PostAdmin(model=Post, session=db.session, category='Blog', name='Posts'))


def build_db():
    sample_posts = [
        {
            'title': "de Finibus Bonorum et Malorum - Part I",
            'content': "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut"
        },
        {
            'title': "de Finibus Bonorum et Malorum - Part II",
            'content': "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque"
        },
        {
            'title': "de Finibus Bonorum et Malorum - Part III",
            'content': "At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium"
        }
    ]

    db.drop_all()
    db.create_all()

    for row in sample_posts:
        post = Post(**row)
        db.session.add(post)

    db.session.commit()


if __name__ == '__main__':
    build_db()
    app.run()