【问题标题】: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 中具有特殊含义。请改用,|

标签: python django django-queryset django-orm


【解决方案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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-09-20
      • 2018-02-02
      • 2011-01-12
      • 1970-01-01
      • 2013-02-13
      • 2019-05-05
      • 2019-10-04
      相关资源
      最近更新 更多