2013-09-23 69 views
5

Tôi cố gắng lấy thông tin chi tiết về người dùng đã được xác thực của tôi trong ứng dụng Django của tôi.apply_authorization_limits không được gọi là

Cho rằng tôi đã tạo ra một tài nguyên mới:

class MyUserResource(ModelResource): 
    class Meta: 
     queryset = ReaderUser.objects.all() 
     resource_name = 'me' 
     list_allowed_methods = [] 
     detail_allowed_methods = ['get'] 
     authorization = Authorization() 
     authentication = SessionAuthentication() 
     excludes = ('password', 'id', 'is_active', 'is_admin', 'last_login') 

    def apply_authorization_limits(self, request, object_list): 
     print request.user 
     return object_list.filter(pk=request.user.pk) 

    def prepend_urls(self): 
     return [ 
      url(r"^(?P<resource_name>%s)/$" % self._meta.resource_name, self.wrap_view('dispatch_detail'), name="api_dispatch_detail"), 
     ] 

Khi tôi gọi API của tôi sử dụng /api/me/?format=json tôi đã nhận như sau: More than one resource is found at this URI.

Tôi cũng đã cố gắng mà không có sự prepend_urls. Điều tôi không hiểu là tuyên bố print không bao giờ được thực thi theo phương pháp apply_authorization_limits

Bất kỳ gợi ý nào về những gì tôi đang làm sai?

Trả lời

4

Tôi đã tìm thấy hai cách để khắc phục vấn đề của mình:

Thứ nhất là hai tạo quyền của riêng tôi.

Trong trường hợp của tôi, sau đây:

from tastypie.authorization import Authorization 

class SimpleReaderAuthorization(Authorization): 
    def read_list(self, object_list, bundle): 
     return object_list.filter(email=bundle.request.user.email) 

Và tôi chỉ cần cập nhật tài nguyên của tôi:

class MyUserResource(ModelResource): 
    class Meta: 
     queryset = ReaderUser.objects.all() 
     resource_name = 'me' 
     list_allowed_methods = ['get'] 
     authorization = SimpleReaderAuthorization() 
     authentication = SessionAuthentication() 
     excludes = ('password', 'id', 'is_active', 'is_admin', 'last_login') 

Một cách đơn giản là để làm những điều sau đây, như đã nêu trong documentation.

def get_object_list(self, request): 
     return super(YourResource, self).get_object_list(request).filter(pk=request.user.pk) 

Kết luận: Tôi đã chọn thứ hai vì nó sạch hơn và đơn giản hơn.

+1

Về giải pháp thứ hai, tôi muốn đi với: 'def get_object (tự, yêu cầu): trả về siêu (YourResource, self) .get_object (pk = request.user.pk) ' Bằng cách này, bạn nhận được 1 đối tượng thay vì danh sách (luôn chứa 1 đối tượng) và bạn tôn trọng kiến ​​trúc REST, yêu cầu http: // blabla/me/12 trong đó 12 là người dùng hiện tại. Con là khi yêu cầu http: // blabla/me/13 (và bạn 12), nó trả về mã HTTP 404. –

+0

@ DavidW.Thanks cho lời khuyên của bạn. Bạn nói đúng, tôi nên quay lại điều này và xem liệu giải pháp của bạn có hợp lý không. –

+0

@DavidD. hoạt động read_list được sử dụng trong danh sách trả về của một số tài nguyên. Để lọc riêng từng itens, bạn có thể sử dụng read_detail để trả về Unauthorized thay vì 404 thành các tài nguyên không được phép. –

0

Tài liệu không hiển thị nhưng apply_authorization_limits được đặt là không dùng nữa. Không chỉ bị phản đối, nó đã bị tách khỏi vòng đời tài nguyên vào tháng 2 năm 2013 bởi this commit. Đó là lý do tại sao nó không được gọi nữa.

Tài liệu được cập nhật tại thời điểm là here và không thay đổi nhiều kể từ đó.

Kiểm tra phiên bản ngon của bạn là 'read_list' được đề xuất bởi số updated documentation.

def read_list(self, object_list, bundle): 
    """ 
    Returns a list of all the objects a user is allowed to read. 

    Should return an empty list if none are allowed. 

    Returns the entire list by default. 
    """ 
    return object_list 

Mã của bạn thay đổi sẽ trông như thế này:

from tastypie.authorization import Authorization 
from tastypie.exceptions import Unauthorized 


class MyAuthorization(Authorization): 
    def read_list(self, object_list, bundle): 
     print request.user 
     return object_list.filter(pk=bundle.request.user.pk) 


class MyUserResource(ModelResource): 
    class Meta: 
     queryset = ReaderUser.objects.all() 
     resource_name = 'me' 
     list_allowed_methods = [] 
     detail_allowed_methods = ['get'] 
     authorization = MyAuthorization() 
     authentication = SessionAuthentication() 
     excludes = ('password', 'id', 'is_active', 'is_admin', 'last_login') 

    def prepend_urls(self): 
     return [ 
      url(r"^(?P<resource_name>%s)/$" % self._meta.resource_name, self.wrap_view('dispatch_detail'), name="api_dispatch_detail"), 
     ] 

Hoặc, bạn có thể sử dụng một Authorization mức tài nguyên (đơn giản hơn nhiều trong trường hợp của bạn):

class MyUserResource(ModelResource): 
    class Meta: 
     queryset = ReaderUser.objects.all() 
     resource_name = 'me' 
     list_allowed_methods = [] 
     detail_allowed_methods = ['get'] 
     authentication = SessionAuthentication() 
     excludes = ('password', 'id', 'is_active', 'is_admin', 'last_login') 

    def authorized_read_list(self, object_list, bundle): 
     print request.user 
     return object_list.filter(pk=bundle.request.user.pk) 

    def prepend_urls(self): 
     return [ 
      url(r"^(?P<resource_name>%s)/$" % self._meta.resource_name, self.wrap_view('dispatch_detail'), name="api_dispatch_detail"), 
     ] 

Lưu ý rằng có không cần meta 'ủy quyền' trong trường hợp này.

Sử dụng meta 'ủy quyền' là tốt nếu bạn có cách phổ biến và chung chung để áp dụng các quyền trên các tài nguyên khác nhau chia sẻ cùng một lớp ủy quyền.