在使用 Django Tastypie 创建简单的 API 时,我遇到了一个问题。我使用了自定义的身份验证(实际上并不算太自定义,因为它直接从他们的示例中复制而来),它只显示当前用户的数据。然而,它却返回了所有用户,而我只想显示已登录的用户。
以下是我当前使用的 api.py 代码:
class UserResource(ModelResource):
class Meta:
queryset = User.objects.all()
excludes = ['password', 'is_superuser']
resource_name = 'user'
authentication=MultiAuthentication(SessionAuthentication(),ApiKeyAuthentication())
authorization=DjangoAuthorization()
allow_methods=['get']
class EntryResource(ModelResource):
user = fields.ForeignKey(UserResource, 'user')
class Meta:
queryset = Entry.objects.all()
resource_name = 'entry'
authentication=MultiAuthentication(SessionAuthentication(),ApiKeyAuthentication())
authorization=UserObjectsOnlyAuthorization()
对于 UserObjectsOnlyAuthorization,我使用了以下代码:
from tastypie.authorization import Authorization
from tastypie.exceptions import Unauthorized
class UserObjectsOnlyAuthorization(Authorization):
def read_list(self, object_list, bundle):
# This assumes a ``QuerySet`` from ``ModelResource``.
return object_list.filter(user=bundle.request.user)
def read_detail(self, object_list, bundle):
# Is the requested object owned by the user?
return bundle.obj.user == bundle.request.user
def create_list(self, object_list, bundle):
# Assuming they're auto-assigned to ``user``.
return object_list
def create_detail(self, object_list, bundle):
return bundle.obj.user == bundle.request.user
def update_list(self, object_list, bundle):
allowed = []
# Since they may not all be saved, iterate over them.
for obj in object_list:
if obj.user == bundle.request.user:
allowed.append(obj)
return allowed
def update_detail(self, object_list, bundle):
return bundle.obj.user == bundle.request.user
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.py 中的 UserResource,就像我为 EntryResource 所做的那样,它会给我报错。如有必要,我可以提供更多详细信息。
2、解决方案
要解决这个问题,您可以定义一个新的 CustomUserAuthorization,并在其中添加一个只允许当前用户访问其信息的过滤器。以下是如何实现的:
from tastypie.authorization import Authorization
from tastypie.exceptions import Unauthorized
class CustomUserAuthorization(Authorization):
def read_list(self, object_list, bundle):
# This you put your filter
return object_list.filter(id=bundle.request.user.id)
def read_detail(self, object_list, bundle):
# This is to check the current user
return bundle.obj.id == bundle.request.user.id
def create_list(self, object_list, bundle):
raise Unauthorized("Sorry, not allowed.")
def create_detail(self, object_list, bundle):
raise Unauthorized("Sorry, not allowed.")
def update_list(self, object_list, bundle):
raise Unauthorized("Sorry, not allowed.")
def update_detail(self, object_list, bundle):
# Only update your details
return bundle.obj.id== bundle.request.user.id
def delete_list(self, object_list, bundle):
raise Unauthorized("Sorry, no deletes.")
def delete_detail(self, object_list, bundle):
raise Unauthorized("Sorry, no deletes.")
在 api.py 中,您可以将此 CustomUserAuthorization 应用于 UserResource:
class UserResource(ModelResource):
class Meta:
queryset = User.objects.all()
excludes = ['password', 'is_superuser']
resource_name = 'user'
authentication=MultiAuthentication(SessionAuthentication(),ApiKeyAuthentication())
authorization=CustomUserAuthorization()
allow_methods=['get']
这样,只有当前用户才能访问其自己的信息。其他用户将无法访问任何数据。
希望这个解决方案能够帮助您解决问题。