在 Django 中使用用户输入构建动态查询
Constructing a dynamic query using user input in Django
我有一个大模型,它存储 10 个基于文本的值和 10 个数值。像这样:
class Dataset(models.Model):
text_field_1 = models.CharField(max_length=255)
.
.
.
text_field_10 = models.CharField(max_length=255)
number_field_1 = models.IntegerField()
.
.
.
number_field_10 = models.IntegerField()
现在,我想要做的是通过将对象传递给视图,为用户提供一种使用这些字段过滤和排序数据集的方法。希望下面的示例显示了我想要做的事情:
obj = {
"filters" : [
"text_field_1='vaccines'",
"number_field_5__gte=1000",
],
"order_by" : "text_field_3, -number_field_7",
"excludes" : [],
}
generate_query(obj) # Dataset.objects.filter(text_field_1='vaccines', number_field_5__gte=1000).order_by('text_field_3', '-number_field_7')
所以通过调用generate_query(obj)
,我们得到了评论中的查询集。现在,由于这个模型的性质,我不可能通过考虑过滤器、订单和排除的所有可能组合来手动执行此操作。
什么是最好的、最安全的实施方式?我唯一想到的是创建一个大字符串,然后使用 exec
或 eval
来执行该字符串。
使用字典进行过滤和排除,使用列表 order_by,您可以使用 *
或 **
的参数解包。
obj = {
"filters" : {
"text_field_1": "vaccines",
"number_field_5__gte": "1000",
},
"order_by" : ["text_field_3", "-number_field_7"],
"excludes" : {},
}
Dataset.objects.filter(**obj['filters']).exclude(**obj['excludes']).order_by(*obj['order_by'])
它应该是相当安全的,只要您不允许用户构建他们自己的 __
参数。例如,过滤器 event__owner__password='hunter2'
可用于间接查询相关模型中的字段。
有一个非常好的软件包专门用于基于用户输入的文件管理:
我有一个大模型,它存储 10 个基于文本的值和 10 个数值。像这样:
class Dataset(models.Model):
text_field_1 = models.CharField(max_length=255)
.
.
.
text_field_10 = models.CharField(max_length=255)
number_field_1 = models.IntegerField()
.
.
.
number_field_10 = models.IntegerField()
现在,我想要做的是通过将对象传递给视图,为用户提供一种使用这些字段过滤和排序数据集的方法。希望下面的示例显示了我想要做的事情:
obj = {
"filters" : [
"text_field_1='vaccines'",
"number_field_5__gte=1000",
],
"order_by" : "text_field_3, -number_field_7",
"excludes" : [],
}
generate_query(obj) # Dataset.objects.filter(text_field_1='vaccines', number_field_5__gte=1000).order_by('text_field_3', '-number_field_7')
所以通过调用generate_query(obj)
,我们得到了评论中的查询集。现在,由于这个模型的性质,我不可能通过考虑过滤器、订单和排除的所有可能组合来手动执行此操作。
什么是最好的、最安全的实施方式?我唯一想到的是创建一个大字符串,然后使用 exec
或 eval
来执行该字符串。
使用字典进行过滤和排除,使用列表 order_by,您可以使用 *
或 **
的参数解包。
obj = {
"filters" : {
"text_field_1": "vaccines",
"number_field_5__gte": "1000",
},
"order_by" : ["text_field_3", "-number_field_7"],
"excludes" : {},
}
Dataset.objects.filter(**obj['filters']).exclude(**obj['excludes']).order_by(*obj['order_by'])
它应该是相当安全的,只要您不允许用户构建他们自己的 __
参数。例如,过滤器 event__owner__password='hunter2'
可用于间接查询相关模型中的字段。
有一个非常好的软件包专门用于基于用户输入的文件管理: