【问题标题】:Django Field Query HandlingDjango 字段查询处理
【发布时间】:2012-12-29 01:09:18
【问题描述】:

我目前正在编写一个项目,该项目在后端使用带有 Django-Rest-Framework 的 Django,在前端使用 Ember.js/Ember-data。

我希望以这种格式将查询从我的 ember 应用程序传递回我的 django api

http://myurl.com/application/api/model/?parameter=X

其中参数是正在查询的模型上的一个字段,X 是要搜索的值。

像这样松散的东西应该是结果查询

queryset = Model.objects.filter(**request.QUERY_PARAMS.dict())

其中 QUERY_PARAMS.dict() 是给出格式字典的 Django 语法

{parameter:X}

** 将 dict 转换为 Django 所期望的关键字参数。
因此上面的行是有效的:

queryset = Model.objects.filter(parameter=X)

我已经使用自定义视图和自定义 mixin 进行了这项工作,但我担心我的查询处理实现可能有点幼稚,这让我觉得这是一种非常常见的模式。

我想知道是否有针对 Django 的库,或者我不完全理解的一些 Django 内部组件可以在没有我的自定义查询集代码的情况下为我处理这些相对常见的查询?

任何正确方向的指点将不胜感激。

史蒂夫·凯恩

编辑:

  def get_integer_queryset(self, query, queryset):
    #stringify the first entry in query.keys (query is request.QUERY_PARAMS)
    query_key = str(query.keys()[0])
    #split the string into individual strings since the request object dict 
    #contains only a string of numbers and not an actual array (see below)
    #query = {'parameter':'1,2,3,4'} becomes {'parameter':['1','2','3','4']}
    query_values = query.get(query_key, None).split(",")
    #construct two dicts.  One handles integers and the other handles "null"
    #all the code below is required because Django does not seem to handle "null"
    #as a valid query to a field that is type "integer"
    #as a side note, I think this is poor and create annoying work...i would love
    #to be wrong here
    #the Q objects are required in order to compose a query of both integers and 
    #the string "null" 
    query_vals_no_null = {query_key+"__in": []} 
    optional_null_dict = {}
    for value in query_values:
      if value == "null" or value == "None":
        optional_null_dict[query_key+"__isnull"] = True
      else:
        query_vals_no_null[query_key+"__in"].append(value)
    return queryset.filter(  Q(**query_vals_no_null) | 
                             Q(**optional_null_dict)   )

这是我从处理整数查询的自定义视图中获取的主要方法。我插入了 cmets 以澄清正在发生的事情。让我知道这是否有帮助或看起来很熟悉/可怕/真棒/有点温和。

史蒂夫

【问题讨论】:

  • 这类似于 django 的旧管理文件系统。但最近,他们添加了验证以确保只能查询特定参数。您可能对此感兴趣,也可能不感兴趣(只需将输入与 VALID_PARAM_KEYS 列表进行比较)。
  • Steve django-rest-framework 社区似乎生活在 google 组而不是 stackoverflow 上(无论好坏)。我还没有像你上面提到的那样做任何自定义查询逻辑,但我想在你得到一个可靠的后端答案后跟进,因为我刚刚完成了 django-rest-framework 的 v1.0 ember-data 适配器和这个似乎是必须具备的功能。 groups.google.com/forum/?fromgroups#!forum/…
  • 我从我的视图中添加了一个方法 sn-p 来展示我处理查询的方法。此方法仅适用于针对“整数”类型字段的查询。它也适用于相关字段,前提是相关字段的引用是整数(通常是 PK)。

标签: django ember.js django-views django-rest-framework


【解决方案1】:

django-filter(以及 REST 框架的相应 django-filter 基于 filter backend)确实是最接近您正在寻找的开箱即用应用程序,但您发现它并不完全支持您需要的用例,主要是因为:

  • 不支持查询字符串中的null/None 键。
  • 不支持使用逗号分隔的__in 样式查找。

(我可能对以上任何一个/两个都错了,但从源代码/文档的角度来看,这就是我的看法)

这意味着您的选择可能是:

  1. 编写您自己的过滤器以完全按照您的需要行事。
  2. 为上述两个问题提供支持至django-filter
  3. 查找 alternative filtering app,并使用它,可能将其包装在 REST 框架过滤器后端,以便在任何所需的视图中更轻松地使用。

我认为 (3) 中的任何选项都不能满足您的需求,尽管您可能想快速深入研究一下美味派和活塞,看看它们是否提供满足您需要的过滤实现,如果确实如此,并以此为基础。

还有一个 alternate filter solution for REST framework 的关闭拉取请求,看起来它确实支持您的 __in 样式过滤。如果这似乎可以满足您的需要,那么值得对票进行评论,我们可以考虑重新打开它,以便在 REST 框架中提供另一个过滤器后端。 (理想情况下作为第 3 方过滤器后端。)

如果您继续使用自己的过滤器解决方案,就像您已经开始做的那样,并最终得到更全面的东西,那么值得在REST framework group 上提及它,以便其他人可以使用它,等等我们可以考虑是否值得将其组合成一个更易于重复使用的 3rd 方包。

通过更新编辑此问题,让我知道您在小组中的进展情况。

【讨论】:

  • 很好的答案。我打算建议 django-filter 但我不知道这些限制。该应用程序在某些方面确实缺乏,并且需要大量工作(并且有人来领导它 - 有很多叉子)。我在工作中经常使用 django-filter,我很惊讶没有更多的人需要类似的功能。
  • @josh - Florian Apolloner 是这些天的主要维护者。他对拉取请求非常敏感,只要它们符合要求。只是需要有人来做这项工作。 ;) 如果您有任何长期存在的问题,可能值得一提,该项目最近有了更多的活动。
  • 你能在你的答案中放一个指向 github repo 的链接吗?我似乎找不到主要项目(只是 alex 的初始回购)。
  • 是的,完成了。 Alex 的仓库是正确的地方,Florian 也对该仓库(以及 PyPI 包)具有写入权限。
  • 谢谢大家。我将检查建议的选项,老实说,我可能会自己编写一个过滤器/查询套件来处理这些用例,并将代码提供给任何可能从中受益的人。
猜你喜欢
  • 2017-05-11
  • 1970-01-01
  • 2013-03-21
  • 1970-01-01
  • 2019-10-27
  • 1970-01-01
  • 2022-10-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多