[英]How to serialize and deserialize Django ORM query (not queryset)?
我的用例是我需要将查询存储在数据库中,并不时检索它们并进行评估。 那是mailing-app所需要的,每个用户都可以订阅由单独定制的查询选择的网站内容。 最基本的解决方案是存储原始SQL并将其与RawQuerySet
一起RawQuerySet
。 但是我想知道是否有更好的解决方案?
乍一看,将查询构建工作交给其他人确实很危险,因为他们可以做任何事情(甚至删除数据库中的所有数据或删除整个表等)。
即使您让他们构建查询的特定部分,它也对Sql Injection开放。 如果所有这些危险都可以,那么您可以尝试以下方法。
这是我使用的旧脚本,允许用户设置查询的特定部分。 基础知识使用string.Template
和eval
(最糟糕的部分)
定义模型:
class SomeModel(Model):
usr = ForeingKey(User)
ct = ForeignKey(ContentType) # we will choose related DB table with this
extra_params = TextField() # store extra filtering criteria in here
让我们执行所有属于用户的查询。 假设我们有一个带有extra_params
is_staff
和'username__iontains'的User
查询
usr:有人
ct:用户
extra_params:is_staff = $ stff_stat,username__icontains ='$ uname'
$
在extra_params中定义占位符
from string import Template
for _qry in SomeModel.objects.filter(usr='somebody'): # filter somebody's queries
cts = Template(_qry.extra_params) # take extras with Template
f_cts = cts.substitute(stff_stat=True, uname='Lennon') # sustitute placeholders with real time filtering values
# f_cts is now `is_staff=True, username__icontains='Lennon'`
qry = Template('_qry.ct.model_class().objects.filter($f_cts)') # Now, use Template again to place our extras into a django `filter` query. We also select related model in here with `_qry.ct.model_class()`
exec_qry = qry.substitute(f_cts=f_cts)
# now we have `User.objects.filter(is_staff=True, username__icontains='Lennon')
query = eval(exec_qry) # lets evaluate it!
如果所有相关导入都已完成,则可以在extra_params中使用Q
或任何其他查询构建选项。 您还可以使用其他方法来构成“ Create
或“ Update
查询。
您可以在此处了解有关Template
表单的更多信息。 但正如我所说。 将这样的选项提供给其他用户是非常危险的 。
另外,您可能需要阅读有关Django内容类型的信息
更新:如@GillBates所述,您可以使用字典结构来创建查询。 在这种情况下,您将不再需要Template
。 您可以使用json进行此类数据传输(如果需要,也可以使用其他方式)。 假设您使用json从外部源获取数据,则以下代码是从头开始的,该步骤使用了上层代码块中的某些变量。
input_data:'{“ is_staff” = true,“ username__icontains” =“列侬”}'
import json
_data = json.loads(input_data)
result_set = _qry.ct.model_class().objects.filter(**_data)
根据您的回答,
用户将一些特定于内容的参数传递到表单中,然后查看接收POST的函数,构造查询
一种选择是存储参数(点刺式或json式,或在模型中),并使用常规django手段重建查询。 由于它可以处理某些数据结构更改,因此它在某种程度上更可靠。
您可以创建一个新的模型user_option
并将选择存储在此表中。 根据您的问题,很难确定它是否是更好的解决方案,但这会使用户的选择在数据结构中更加明确。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.