python-从asteapie的资源中删除列表端点
作者:互联网
我的api上有一个总是返回登录用户的资源.该资源是只读的.
我希望列表uri充当详细信息uri,并删除详细信息网址.
因此,/ api / v1 / user /将返回记录的用户,而其他任何URL都会失败.
这是我为实现这一目标所做的:
class UserResource(ModelResource):
class Meta:
queryset = User.objects.all()
fields = ['email', 'name']
authentication = MultiAuthentication(SessionAuthentication(), BasicAuthentication())
authorization = Authorization()
list_allowed_methods = []
detail_allowed_methods = ['get']
def base_urls(self):
'''
The list endpoint behaves as the list endpoint.
'''
return [
url(r"^(?P<resource_name>%s)%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('dispatch_detail'), name="api_dispatch_detail"),
url(r"^(?P<resource_name>%s)/schema%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('get_schema'), name="api_get_schema")
]
def obj_get(self, bundle, **kwargs):
'''
Always returns the logged in user.
'''
return bundle.request.user
def get_resource_uri(self, bundle_or_obj=None, url_name='api_dispatch_detail'):
bundle_or_obj = None
try:
return self._build_reverse_url(url_name, kwargs=self.resource_uri_kwargs(bundle_or_obj))
except NoReverseMatch:
return ''
我使用base_urls()而不是prepend_urls(),因为我想删除其他网址.
它工作正常,但是当我打/ api / v1 / url时,出现此错误:
Traceback:
File "/home/vagrant/workspace/expenses/venv/local/lib/python2.7/site-packages/Django-1.5-py2.7.egg/django/core/handlers/base.py" in get_response
115. response = callback(request, *callback_args, **callback_kwargs)
File "/home/vagrant/workspace/expenses/venv/local/lib/python2.7/site-packages/django_tastypie-0.9.15-py2.7.egg/tastypie/api.py" in wrapper
80. return getattr(self, view)(request, *args, **kwargs)
File "/home/vagrant/workspace/expenses/venv/local/lib/python2.7/site-packages/django_tastypie-0.9.15-py2.7.egg/tastypie/api.py" in top_level
137. 'resource_name': name,
File "/home/vagrant/workspace/expenses/venv/local/lib/python2.7/site-packages/django_tastypie-0.9.15-py2.7.egg/tastypie/api.py" in _build_reverse_url
166. return reverse(name, args=args, kwargs=kwargs)
File "/home/vagrant/workspace/expenses/venv/local/lib/python2.7/site-packages/Django-1.5-py2.7.egg/django/core/urlresolvers.py" in reverse
496. return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))
File "/home/vagrant/workspace/expenses/venv/local/lib/python2.7/site-packages/Django-1.5-py2.7.egg/django/core/urlresolvers.py" in _reverse_with_prefix
416. "arguments '%s' not found." % (lookup_view_s, args, kwargs))
Exception Type: NoReverseMatch at /api/v1/
Exception Value: Reverse for 'api_dispatch_list' with arguments '()' and keyword arguments '{'api_name': u'v1', 'resource_name': 'user'}' not found.
它正在尝试到达缺少的列表端点.我该如何摆脱呢?
谢谢.
感谢Rudy的指导,我得出以下结论:
class UserResource(ModelResource):
class Meta:
queryset = User.objects.all()
fields = ['email', 'name']
authentication = MultiAuthentication(SessionAuthentication(), BasicAuthentication())
authorization = Authorization()
list_allowed_methods = []
detail_allowed_methods = ['get']
def dispatch_list(self, request, **kwargs):
return self.dispatch_detail(request, **kwargs)
def obj_get(self, bundle, **kwargs):
'''
Always returns the logged in user.
'''
return bundle.request.user
def get_resource_uri(self, bundle_or_obj=None, url_name='api_dispatch_list'):
bundle_or_obj = None
try:
return self._build_reverse_url(url_name, kwargs=self.resource_uri_kwargs(bundle_or_obj))
except NoReverseMatch:
return ''
解决方法:
您应该使用一个自定义的Authorization类来阻止列表端点,并优雅地引发一个错误,而不是将URL一起删除,这样它仍然可以与Deliciouspie很好地配合使用.
class UserObjectsOnlyAuthorization(Authorization):
def read_list(self, object_list, bundle):
raise Unauthorized("Sorry, no list reads.")
def read_detail(self, object_list, bundle):
# Is the requested object the user?
return bundle.obj == bundle.request.user
def create_list(self, object_list, bundle):
raise Unauthorized("Sorry, no creates.")
def create_detail(self, object_list, bundle):
raise Unauthorized("Sorry, no creates.")
def update_list(self, object_list, bundle):
raise Unauthorized("Sorry, no updates.")
def update_detail(self, object_list, bundle):
raise Unauthorized("Sorry, no updates.")
def delete_list(self, object_list, bundle):
# Sorry user, no deletes for you!
raise Unauthorized("Sorry, no deletes.")
def delete_detail(self, object_list, bundle):
raise Unauthorized("Sorry, no deletes.")
编辑:
如果您想强制将此API始终作为“详细信息”请求,则可以覆盖Tastypie的内置函数.基本上,如果您在URL中指定一个ID,则tastypie将其路由为_detail请求,如果未指定,则将其路由为_list请求.如果您覆盖了检测到此的调度功能,则可以将此资源的所有请求更改为_detail,并指定查找用户的主键.这可能有点棘手,但可以实现您想要的功能:
def dispatch(self, request_type, request, **kwargs):
# Force this to be a single User object
return super(UserResource, self).dispatch('detail', request, **kwargs)
def get_detail(self, request, **kwargs):
# Place the authenticated user's id in the get detail request
kwargs['id'] = request.user.pk
return super(UserResource, self).get_detail(request, **kwargs)
标签:rest,tastypie,python 来源: https://codeday.me/bug/20191030/1971422.html