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 修改的理由。
鉴于 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
andobj_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 修改的理由。