python - 如何序列化和反序列化 Django ORM 查询(不是查询集)?

标签 python sql django serialization

我的用例是我需要将查询存储在数据库中并不时检索它们并进行评估。这是邮件应用程序所需要的,每个用户都可以订阅通过单独定制的查询选择的网站内容。 最基本的解决方案是存储原始 SQL 并将其与 RawQuerySet 一起使用。但我想知道是否有更好的解决方案?

最佳答案

乍一看,将查询构建工作交给其他人确实很危险,因为他们可以做任何事情(甚至删除数据库中的所有数据或删除整个表等)

即使您让他们构建查询的特定部分,它仍然对 Sql Injection 开放.如果所有这些危险都没有问题,那么您可以尝试以下操作。

这是我使用的旧脚本,让用户设置查询的特定部分。基础是使用 string.Templateeval(邪恶的部分)

定义模型:

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

让我们执行属于用户的所有查询。假设我们有一个 User 查询,其中包含 extra_params is_staff 和 'username__iontains'

usr: somebody

ct: User

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 或任何其他查询构建选项。您也可以使用其他方法来形成CreateUpdate 查询。

您可以阅读更多关于 Template 的信息在那里形成。但正如我所说。将此类选项提供给其他用户真的很危险

您可能还需要阅读有关 Django Content Type 的内容

更新:如@GillBates 所述,您可以使用字典结构来创建查询。在这种情况下,您将不再需要 Template。您可以使用 json 进行此类数据传输(如果您愿意,也可以使用任何其他格式)。假设您使用 json 从外部源获取数据,下面的代码是使用上层代码块中的一些变量的草稿。

input_data : '{"is_staff"=true, "username__icontains"="Lennon"}'

import json
_data = json.loads(input_data)
result_set = _qry.ct.model_class().objects.filter(**_data)

关于python - 如何序列化和反序列化 Django ORM 查询(不是查询集)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19560838/

相关文章:

python - 在 Django 表单中禁用 BooleanField 的更改

python - 在python中通过Selenium Webdriver下载文件

sql - 根据最大值连接表

python - 在 Ubuntu 12.04 上从 Django 1.6 升级到 1.7

python - Python比较列表

sql - Postgres 中的多表 count()

php - 仅当更新另一个表上的列或将新记录添加到该另一个表时,才将记录插入到新的 MySQL 数据库表中?

python - 如何在迁移过程中重命名 Django 模型中的函数而不会导致 AttributeError

django - 无法在 Django Rest Framework 序列化程序的 valid_data 中获取非模型字段

python - 嵌套字典到 MultiIndex pandas DataFrame(3 级)