有没有办法检查字符串是不是是 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__icontains
、field__gte
等扩展名。因此需要做更多的工作。
免责声明:try
/except
是更好的方法。我不知道您为什么要关闭此方法。
【讨论】:
【参考方案2】:简短的回答是否定的,但还有其他选择。
Django 不提供,也不便于创建您所询问的那种验证功能。您不仅可以过滤字段和正向关系,还可以过滤反向关系,在完全不同的模型中的字段上的related_name
或related_query_name
可能是用于过滤查询集的valid way。并且有各种过滤机制,如iexact
、startswith
、regex
等,作为这些关系名称的后缀是有效的。因此,要正确验证所有内容,您需要复制大量 Django 的内部解析代码,这将是一个很大的错误。
如果您只想按此模型的字段和转发关系进行过滤,您可以使用hasattr(SomeModel, my_str)
,但这并不总是正确的(您的模型除了字段之外还有其他属性,例如方法和属性)。
您至少可以捕获在过滤 kwargs (it's TypeError
) 中使用无效字符串时将引发的特定错误,而不是做一揽子 except: pass
。您还可以返回 400 错误,让客户端知道他们的请求无效,而不是默默地继续使用未过滤的查询集。
我首选的解决方案是将这种样板、可概括的逻辑外包给一个库,例如 dynamic-rest。
【讨论】:
以上是关于有没有办法检查字符串是不是是 django 查询集的有效过滤器?的主要内容,如果未能解决你的问题,请参考以下文章