django 设计模式/最佳实践:过滤查询集
Posted
技术标签:
【中文标题】django 设计模式/最佳实践:过滤查询集【英文标题】:django design pattern/best practice: filtering a queryset 【发布时间】:2012-09-26 03:01:13 【问题描述】:我有一个向用户显示查询集结果的页面。 我想做的是允许用户单击链接以应用过滤器。
目前我所做的是让链接将“get”参数传递给页面以应用过滤器。过滤器可以引用其他模型或自定义过滤器(例如未分配的过滤器)
为了提供良好的用户体验,实现需要做一些事情
在视图中:-
检查传递的过滤参数是否有效
检查它是什么类型的过滤器(基于其他模型或自定义过滤器),以便将正确的条件应用于查询集
(可选)一种使过滤器累积的方法(即您可以继续添加过滤器)
-
根据选择的过滤器显示正确的结果集
在显示过滤器时,识别我们应用了哪个过滤器,以便当前应用的过滤器显示为文本而不是超链接。
我认为这必须足够普遍,以至于除了视图和模板中明显的 if/else 语句之外,有人必须为此找到类似的设计模式或最佳实践。
有吗?
【问题讨论】:
【参考方案1】:我发现 Django 管理员处理这种功能的方式是一个很好的模式。如果您不熟悉,请查看管理员中的 list_filter
选项。它与您所描述的相似,但您的更通用。也许这会帮助你思考一些想法?
首先,对于实际的查询字符串块,您只需传递 Django-ORM 查找键和值对。例如,?sites__id__exact=1
、tags__in=words
等。由于您希望允许跨模型查找,您需要在字符串中提供其他部分以包含模型名称,不要太难。
为了检查过滤器是否有效,您可以简单地确保模型/字段查找有效。通过拆分每个 QS 块的部分,您可以识别模型、字段名、查找和值。然后,使用 Django 的内置功能来验证模型上是否存在字段名。您也可以使用 ForeignKey 来做到这一点。 Here's how Django does it
您可以很容易地继续添加过滤器。您将提供您的视图和显示这些过滤器的表单以及一些上下文,因此它将为用户保留并重新填充。此外,您可以轻松地保留查询字符串。基本上,您在这里始终拥有相同的读取/解析功能,没有什么不同。
我认为密钥是自动化的,并尽可能保持干燥。不要屈服于一堆 if 语句。将这些查找传递到 ORM 真的很容易,也很安全,而且很容易捕获错误的查找并向用户提供有意义的错误消息。
我希望这对您的道路有所帮助! :)
【讨论】:
谢谢巴泰克。我担心在 GET 参数中使用实际键。即使它们是有效的,它们仍然可能是不受欢迎的(例如,允许用户收回他们不应该访问的信息)。 当然,但是您可以在构建查询时设置权限处理。以上是关于django 设计模式/最佳实践:过滤查询集的主要内容,如果未能解决你的问题,请参考以下文章
仅当过滤器值不是空字符串、空格或空值时过滤 MySQL 查询最佳实践