Tastypie 数据库级别字段选择

Tastypie DB level Field Selection

鉴于 PostgreSQL 9.2.10、Django 1.8、python 2.7.5 和 django-tastypie 0.12.1:

我正在尝试弄清楚如何根据自定义参数(字段 selection)为 tastypie 执行动态查询集,最终用户可能会通过这样的方式进行过滤:

https://example.com/api/v1/resource/?fields=field1(列表视图)
https://example.com/api/v1/resource/1/?fields=field1(详细视图)

def dehydrate()(未使用):
dehydrate 中实现这个很好,但是由于数据已经 'dehydrated' 我实现的唯一收获是由于删除了 unselected 字段,响应变小了。此 HERE.

的代码

def full_dehydrate()(目前正在使用):
full_dehydrate 中实现这个更好,因为我跳过了我没有 [=76] 的字段上的初始 'dehydate' =].这比上面的 dehydrate 方法更快更有效。 HERE.

的代码

虽然这两种方法没有在数据库级别实现过滤器(我仍在做一个 model.objects.all()). This is fine in a dev instance where my db is MORE than likely local to the application/api itself, however in prod (in my case) the db is on a separate server. So my question is this, is there a way that I can dynamically change my tastypie query filter for a given resource based off of params passed in the API request? get_object_list looks promising but I am unsure if this is the method to pursue or if I should be writing a custom filter to add in via build_filters (I am assuming a build_filter is better,, though every example I see with custom build filters also requires a appy_filter for some reason.). Also I am unsure as to what that would look like for the particular scenario, as the method used to get request params is bundle.request 这两种方法中没有。

感谢所有花时间阅读本文的人,并非常感谢提供有效解决方案的任何人。我非常感谢所提供答案背后的帮助和思考过程。

** 编辑 1 **
HERE 很好地形象化了这个过滤器需要发生的过程(希望这有助于激发一些想法)

** TL;DR **
我想允许基于最终用户可能在 API 请求(read: 动态修改资源queryset).

您似乎想在生成的 Django SELECT 子句上设置特定字段。为此,您需要使用 Django 查询集中的 only() and defer() 方法。一种或另一种的使用完全取决于您的需要。

现在,您需要在访问项目之前在查询集上调用该方法。 Tastypie Resource 的 build_filters() 在这种情况下没有用,因为它与查询集的 filter() 将接收的参数有关。 apply_filters() 听起来是个不错的选择,但我不会把它放在那里,因为我们不是在修改过滤 (WHERE),而是在修改 selection (SELECT)。最后,我会在 obj_get_list() 中进行相应的修改,就在 apply_filters() 调用之后。

我正在为您提供满足您需求的 Gist HERE。如要点中所述:

This has to be done in two parts:

1) In model queryset for database selection. This need to be in some code section where the queryset is ready, but still not evaluated. obj_get_list and obj_get are perfect for Tastypie GET requests.

2) In full_dehydrate method, to prevent from Tastypie fetching all the fields from the model.

您提出的 dehydrate() 的要点似乎没有必要,因为 full_dehydrate() 已经只选择了 selected 字段。

注意: 作为记录,在查询集上使用 only()defer(),然后尝试访问未 selected模型上的字段导致单独 SQL 调用请求的额外字段。所以要小心总是 select 需要的字段,特别是在对象列表中,因为不这样做会生成 n*m 次调用,n 是以后访问的未selected 字段的数量,m 是数量查询的对象。这是 full_dehydrate() Gist 修改的理由。