我正在用Django和DjangoRestFramework为我的学校写一个内部应用程序。它是用Microsoft Access 2003编写的一个非常旧的自主开发应用程序的替代品。我的用户非常希望拥有的一个功能是,不仅可以通过精确的数量搜索字段(例如,donation表中的donation_amount ),而且可以使用如下查询进行搜索:
< 130 and > 125Access目前允许这种功能,而且非常有用,但是我完全不知道有什么方法可以在不将查询直接插入到SQL中(非常危险)或在Python表达式中使用eval (甚至更危险)的情况下实现这样的功能。
是否有任何库或子语言允许这样做?
发布于 2014-11-19 20:28:29
我不熟悉Django生态系统,但是Python标准库包含ast.parse,它解析有效的Python表达式字符串并生成抽象语法树,您可以将其剖析并转换为查询-或者一系列函数调用,或者您需要的任何东西。因此,如果你不能找到更具体的东西,那么这可能是有用的。
这段代码:
ast.parse('donation_amount < 130 and donation_amount > 125')返回以下AST结构:
ast.Module(
ast.Expr([
ast.BoolOp(ast.And(), [
ast.Compare(
[ast.Lt()],
ast.Name('donation_amount', ast.Load()),
[ast.Num(130)]),
ast.Compare(
[ast.Gt()],
ast.Name('donation_amount', ast.Load()),
[ast.Num(125)])])]))因此,这将负责解析,但您仍然需要将其转换为您自己的查询。但是看起来你只需要处理少量的节点类型:
BoolOp -> and, or
Compare -> ==, !=, >, <, >=, <=, in, not in
Name -> identifiers (column names, true/false/null, etc.)
Num -> numbers
Str -> strings如果您想要支持数据库功能,还可以选择ast.Call节点;如果您想要支持IN功能,还可以选择ast.Tuple或ast.List节点。如果AST包含任何其他节点类型,则可以将其视为无效查询而拒绝。
发布于 2014-11-19 18:12:37
您是否使用Django ORM对数据库进行建模?如果是这样的话,这不是可以归结为:
Donation.objects.filter(donation_amount__lte=130).filter(donation_amount__gte=125)https://stackoverflow.com/questions/27013945
复制相似问题