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

时间:2016-10-11 21:13:07

标签: python django django-queryset django-orm

我正在尝试添加一些功能,以便用户能够通过URL get参数过滤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}) 

2 个答案:

答案 0 :(得分:1)

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

qs.model._meta.get_all_field_names()

您可能还希望使用field__icontainsfield__gte等扩展程序。因此需要做更多工作。

免责声明try / except是最优秀的方式。我不知道你为什么想要解雇这种方法。

答案 1 :(得分:0)

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

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

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

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

我首选的解决方案是将这种样板,可推广逻辑外包给库,例如dynamic-rest