有没有办法检查字符串是不是是 django 查询集的有效过滤器?

Posted

技术标签:

【中文标题】有没有办法检查字符串是不是是 django 查询集的有效过滤器?【英文标题】:Is there a way to check if a string is a valid filter for a django queryset?有没有办法检查字符串是否是 django 查询集的有效过滤器? 【发布时间】:2017-02-20 13:27:16 【问题描述】:

我正在尝试添加一些功能,让用户能够通过 URL 获取参数在 Django 中过滤分页查询集,并且已成功运行:

for f in self.request.GET.getlist('f'):
    try:
        k,v = f.split(':', 1)
        queryset = queryset.filter(**k:v)
    except:
        pass

但是,我希望以不使用 try/except 块的方式这样做。 django 中是否有标准方法来检查字符串是否为有效的过滤器参数?

例如:

my_str = "bad_string_not_in_database"
if some_queryset.is_valid_filter_string(my_str):
   some_queryset.filter(**my_str:100) 

【问题讨论】:

如果我理解正确,您可以从链接中找到信息:docs.djangoproject.com/en/1.10/topics/db/managers 我不想向自定义管理器添加额外的命令,我想知道这种方式是否已经存在。 如果它是“第一”级过滤器,则可能在您的模型上具有属性。 这实际上几乎是重复的。这是一个做if来找出模型字段是否存在或做一个try except的问题。这些是实现这一目标的唯一可能方法。所以问题归结为什么更好 我注意到您正在使用 : 字符拆分字段。不要那样做,它是 RFC 1738 保留字符,在 URL 中具有特殊含义。请改用,| 【参考方案1】:

您可以从查看字段名称开始:

qs.model._meta.get_all_field_names()

您可能还想使用诸如field__icontainsfield__gte 等扩展名。因此需要做更多的工作。

免责声明try/except 是更好的方法。我不知道您为什么要关闭此方法。

【讨论】:

【参考方案2】:

简短的回答是否定的,但还有其他选择。

Django 不提供,也不便于创建您所询问的那种验证功能。您不仅可以过滤字段和正向关系,还可以过滤反向关系,在完全不同的模型中的字段上的related_namerelated_query_name 可能是用于过滤查询集的valid way。并且有各种过滤机制,如iexactstartswithregex 等,作为这些关系名称的后缀是有效的。因此,要正确验证所有内容,您需要复制大量 Django 的内部解析代码,这将是一个很大的错误。

如果您只想按此模型的字段和转发关系进行过滤,您可以使用hasattr(SomeModel, my_str),但这并不总是正确的(您的模型除了字段之外还有其他属性,例如方法和属性)。

您至少可以捕获在过滤 kwargs (it's TypeError) 中使用无效字符串时将引发的特定错误,而不是做一揽子 except: pass。您还可以返回 400 错误,让客户端知道他们的请求无效,而不是默默地继续使用未过滤的查询集。

我首选的解决方案是将这种样板、可概括的逻辑外包给一个库,例如 dynamic-rest。

【讨论】:

以上是关于有没有办法检查字符串是不是是 django 查询集的有效过滤器?的主要内容,如果未能解决你的问题,请参考以下文章

检查两个 Django 查询集是不是有任何共同的项目

当查询被填充时,有没有办法在 Django 模板中呈现大型查询集?

合并或联合动态创建的查询集列表 - Django

如何检查一个元素是不是存在于 Django 查询集中?

检查 django 中的空查询集

Django,有没有办法看到正在执行的SQL查询?