大家好,是否可以根据操作显示不同的资源字段。
我想要它的原因是为了避免资源包含的所有 has_many 字段的索引操作负担。
例如,在作者索引视图中,我只想返回他的名字,但对于显示操作,我想包括所有书籍资源。
谢谢,
博扬
+1
非常希望有这个功能:“明细栏”和“列表栏”可以分开
+1(通过#44 重复)
在我看来,有两件事可以更轻松地在索引操作中获取数据子集:
元:
index_exclude_fields = ['some_m2m_field']
这将允许我们保存一些数据库查询。
我没有评估 1. 会影响缓存。
你怎么认为?
同样在#48 中被欺骗,但每个问题都有值得关注的方面。
如果可以的话,我想推出这个功能,但我已经被淘汰了。 无论如何,它需要在那里以获得更好的文件支持,所以它必须得到解决。 将以此为目标 1.0。
在进一步检查我的用例之后,我建议将其实现为比仅显示/列表视图更灵活的东西。 我真正需要做的是采用这样的查询字符串标志:
&shape=[完整|简单|无]
并让输出反映用户选择的详细程度。 我寻找了一种方法来解决这个问题,但是由于在创建 ModelResource 类时包含/排除了字段,我无法想出任何方法来更改响应周期后期可用的内容。 此外,请求对象在我想要做出此类决定的过程中的步骤中不可用。
+1
我会首先在这里提到这个想法,因为它似乎与这个问题有关,但它可能需要独立出来。
如果开发了一种显示不同字段的机制,如果它也可以与身份验证集成在一起,那将会很有用。 能够公开更多/更少的字段取决于用户的权限将是非常强大的。 如果这已经可能,我还没有找到任何提及。
+1
+1
+1
+1
+1
+1
+1
除了列表/详细信息之外,我希望能够控制每个方法(POST、PUT、GET)上显示的字段(使用字段或排除)。
这是一种解决方法,请参见下面的示例:您不会从原始模型的资源模型(示例中的 UserResource)中排除任何内容,因此它在索引视图中会是完整的。 您必须进入包含您的子模型(BlogPostResource 中包含作者)的模型资源的脱水方法,然后删除包的元素。
例子:
class BlogPostResource(ModelResource):
author = fields.ForeignKey(UserResource, 'author', full=True)
....
class Meta:
...
def dehydrate(self, bundle):
del bundle.data['author'].data['field_you_dont_wanna_show_here']
del bundle.data['author'].data['field_you_dont_wanna_show_here']
return bundle
因此,当您想列出用户时,您仍然可以获得所有字段,但是当您列出博客文章时,您可以例如只获取作者的名字和姓氏。
你怎么认为?
一个非常非常脏的解决方法的示例:不在 list_view 中显示项目字段,但在 detail_view 中显示,而无需访问资源本身,无需硬编码即可获取 url 本身应该是可行的,但还没有时间查看:
class CompanyResource(ModelResource):
"""
Tastypie resource for Company
"""
projects = fields.ToManyField('api.resources.ProjectResource',
'projects',full=True)
class Meta:
queryset = Company.objects.all()
resource_name = 'companies'
def dehydrate(self, bundle):
if bundle.request.path == "/api/v1/companies/":
del bundle.data['projects']
return bundle
+1
+1
+1
我也会跳上火车,坐火车会很好,但@ashwoods指出的内容足以让我
def dehydrate(self, bundle):
if self.get_resource_uri(bundle) == bundle.request.path:
print "Detail"
if self.get_resource_uri(bundle) != bundle.request.path:
print "Not Detail - Could be list or reverse relationship."
return bundle
所以我对此进行了更多思考,并提出了一些非常接近于让我做我认为@bmihelac正在寻找的事情。
使用@ashwoods提供的示例,假设我们只想显示项目字段,如果它是详细响应:
class CompanyResource(ModelResource):
"""
Tastypie resource for Company
"""
class Meta:
queryset = Company.objects.all()
resource_name = 'companies'
additional_detail_fields = {'projects': fields.ToManyField('api.resources.ProjectResource', 'projects',full=True)}
def dehydrate(self, bundle):
# detect if detail
if self.get_resource_uri(bundle) == bundle.request.path:
# detail detected, include additional fields
bundle = self.detail_dehydrate(bundle)
return bundle
# detail_dehydrate is basically full_dehydrate
# except we'll loop over the additional_detail_fields
# and we won't want to do the dehydrate(bundle) at the end
def detail_dehydrate(self, bundle):
"""
Given a bundle with an object instance, extract the information from it
to populate the resource.
"""
# Dehydrate each field.
# loop over additional_detail_fields instead
#for field_name, field_object in self.fields.items():
for field_name, field_object in self._meta.additional_detail_fields.items():
# A touch leaky but it makes URI resolution work.
if getattr(field_object, 'dehydrated_type', None) == 'related':
field_object.api_name = self._meta.api_name
field_object.resource_name = self._meta.resource_name
bundle.data[field_name] = field_object.dehydrate(bundle)
# Check for an optional method to do further dehydration.
method = getattr(self, "dehydrate_%s" % field_name, None)
if method:
bundle.data[field_name] = method(bundle)
# dehydrating the bundle will create an infinite loop
#bundle = self.dehydrate(bundle)
return bundle
+1,暂时使用
+1
+1
#526 中的部分实现,不确定我是否已全部出售并且缺少测试/文档。
刚看到这张票......也喜欢上面onyxfish提到的“形状”方法......
想我在#526 中的解决方案有点有限,以防人们在其他情况下想要不同的“形状”......
脱水后删除字段的建议......我的全部原因是首先避免计算值。
但是,我喜欢 detail_dehydrate 钩子允许有条件地添加更多细节的想法。
看起来有两种可能的实现,包括测试和文档。 我在 #569 和 #538 中写了一个也执行类似的功能(#538 允许更多的灵活性,因为use_in
可能是可调用的)。 我的实现添加了meta
属性来控制此功能(与当前的fields
属性一致),而 #538 向字段添加了一个属性。 两者似乎都有效,只是关于走哪条路的设计决定。 添加到元对我来说似乎是一致的,并且更容易使用,因为某些字段可以自动生成并且可能无法修改它们的初始化参数。 另一种选择是结合两个拉取请求并允许根据meta
属性自动设置use_in
参数,但是这似乎给 API 增加了不必要的复杂性。 感谢@issackelly向我指出相关的拉取请求。
[因为我是#538 背后的原始原因,这是对我的#526 的清理]
很有意义...... Meta 方法确实会与 ModelResource 的排除列表结合,等等......
正如我在另一张票中所说的那样,恕我直言,这样的“简单”解决方案足以满足 1.0 版本的需求……而更复杂的解决方案,例如“客户端可选择的‘形状’”可能是以后版本所需要的。 .
@funkybob同意,当然更复杂的解决方案对客户端会有所帮助,但是尽快包含此功能会很好,以便可以在 1.0 发布之前开始使用。
实际上在生产应用中使用 PR,我非常喜欢#538 提供的回调的灵活性。 我有几个用例,我必须在运行时根据权限隐藏资源。
这对我来说是不可能的 #569
你好,有消息吗? 那个公关让生活变得更轻松,谢谢!
使用@dericcrago 提供的 hack
+1
我正在使用的一个简单解决方法是覆盖get_detail
和get_list
方法来编辑这些字段。
这节省了实际获取字段数据然后从包中删除它的开销,但我不确定这个方法是否是线程安全的,因为看起来资源对象不是在每次 api 调用时创建的。
如果有人可以对此发表评论,那就太好了。
这是代码:
class ArticleResource(BaseModelResource):
owner = fields.ToOneField(UserResource, 'owner', full=True)
class Meta:
resource_name = "articles"
def get_list(self, request, **kwargs):
self.fields.pop("comments", None)
return super(ArticleResource, self).get_list(request, **kwargs)
def get_detail(self, request, **kwargs):
self.fields["comments"] = fields.ToManyField(CommentResource, 'comments', full=True)
return super(ArticleResource, self).get_detail(request, **kwargs)
+1
另一种解决方法是为详细信息和列表视图使用不同的资源:
from tastypie.resources import ModelResource
from django.contrib.auth.models import User
# detail will show everything except password
class UserResourceDetail(ModelResource):
class Meta:
queryset = User.objects.all()
excludes = ('password',)
resource_name = 'user'
# list will only show username & date_joined (and exclude password)
class UserResource(UserResourceDetail):
class Meta(UserResourceDetail.Meta):
fields = ('username', 'date_joined')
get_detail = UserResourceDetail().get_detail
# ... register & use UserResource
+1
+1 @dnozay解决方法
+1 @dnozay ,真棒
请注意,如果您希望get_resource_uri
与用户详细信息视图一起正常工作,则需要在定义UserResource
后添加以下内容。
UserResourceDetail.get_resource_uri = UserResource().get_resource_uri
否则,所有详细响应中的resource_uri
将为空。
可能相关:#1265
最有用的评论
我正在使用的一个简单解决方法是覆盖
get_detail
和get_list
方法来编辑这些字段。这节省了实际获取字段数据然后从包中删除它的开销,但我不确定这个方法是否是线程安全的,因为看起来资源对象不是在每次 api 调用时创建的。
如果有人可以对此发表评论,那就太好了。
这是代码: