2014-07-20 5 views
0

Tastypie 및 Django를 실험하고 있으며 수행 할 수 있는지 궁금합니다. 설명해 드리겠습니다 ...사용자를 생성하기 위해 특정 HTTP 메소드에 대해 tastypie의 기본 인증을 사용하지 않음

내 API의 일부로 사용자 지정 사용자 자원 (및 모델)이 있습니다. 이 리소스를 통해 사용자를 업데이트 할 수 있기를 바랍니다. 사용자가 소유자 만 업데이트 할 수 있도록하기 위해 tastypie.authentication.BasicAuthentication을 사용 설정했습니다 (put_detail 방법을 통해 이루어짐).

문제는이 리소스를 통해 사용자를 만들 수 있기를 원합니다.이 리소스에 액세스하려면 로그인 자격 증명이 필요하므로 BasicAuthentication 때문에 완료 할 수 없습니다.

그래서, 나는 다음과 같은 옵션을 가지고있는 것처럼 느낄 : POST 요청에 대한

  1. 어떻게 든 비활성화 인증 (I 무엇을 시도했다에서 가능하지 않는 것).
  2. 인증 양식이 없지만 POST 요청 만 허용하는 두 번째 모델 리소스를 만듭니다 (이 시도했지만 다음 문제가 발생했습니다).
    1. 원본 모델 리소스의 이름은 user입니다. 이상적으로이 두 번째 리소스의 이름을 user/create으로 지정하고 싶지만 URL은 user 모델로 선택되었으므로 절대로 올바르게 해결되지 않습니다. tastypie가로 해석 때문에 내가 두번째 접근 방식을 시도한 것입니다

...

class UserResource(ModelResource): 
    ... 

    class Meta: 
     resource_name = 'users' 
     queryset = CustomUser.objects.all() 
     authentication = BasicAuthentication() 
     detail_allowed_methods = ['get', 'put'] 

    def put_detail(self, request, **kwargs): 
     # stub 
     return HttpAccepted('User updated.') 


class CreateUserResource(ModelResource): 
    class Meta: 
     resource_name = 'users/create' 
     queryset = CustomUser.objects.all() 
     # No authentication 
     list_allowed_methods = ['post'] 

    def post_list(self, request, **kwargs): 
     # stub 
     return HttpCreated('User created.') 

내가 api/v1/users/create에 POST를 한 경우, 그것은, CreateUserResource에 의해 처리되지 않습니다 UsersResource에 대한 세부 정보보기 및 그 이후에 나는 404를 얻습니다. 012ast47.gif tastypie가 리소스에 대한 URL을 검색하는 순서를 변경할 수 있습니까?

리소스가 내 urls.py 파일에 등록 된 순서는 차이가없는 것 같습니다. 아니면 내가 구현하고 싶은 것에 더 적합 할 수있는 대안이 있습니까?

답변

0

좋아, 나는 UserResource 모델에 대해 dispatch 메서드를 재정 의하여 방법 1을 사용하여이 작업을 수행했습니다. 워드 프로세서 [link]에서 :

  • dispatch은 무거운 짐을 잔뜩 않습니다. 그것은 보장 :
    • 요청 HTTP 방법 allowed_methods (method_check)이고,
    • 클래스는 사용자가 인증
    • 요청 (get_list)를 처리 할 수있는 방법 (is_authenticated)이,
    • 을 사용자는 (is_authorized),
    • & 사용자가 스로틀 (throttle_check)을 초과하지 않았 음을 인증합니다.
    • 이 시점에서

는 파견 실제로 요청 방법 (get_list을)를 호출합니다.

지금, 나는 is_authenticated 단계를 무시하고 싶었지만에만 request 경우 '목록'유형으로 "POST"입니다. 내 구현을위한 코드는 다음과 같습니다.

from django.http import HttpResponse 
from tastypie.http import HttpAccepted, HttpBadRequest, HttpCreated, HttpNoContent, HttpNotImplemented 
from tastypie.authentication import BasicAuthentication 
from tastypie.exceptions import ImmediateHttpResponse 
from tastypie.fields import IntegerField, ToManyField 
from tastypie.resources import ModelResource, convert_post_to_put 

from <your_user_module> import User  

class UserResource(ModelResource): 
    ... 

    class Meta: 
     resource_name = 'users' 
     queryset = User.objects.all() 

     authentication = BasicAuthentication() 

     list_allowed_methods = ['get', 'post'] 
     detail_allowed_methods = ['get'] 

    # Bypasses the authentication process if the request is a 
    # POST to the 'list'. The code within the 'if' block is 
    # taken from 'tastypie.resources.Resource.dispatch()' 
    def dispatch_list(self, request, **kwargs): 
     if request.method == 'POST': 
      request_type = 'list' 
      allowed_methods = getattr(self._meta, "%s_allowed_methods" % request_type, None) 

      if 'HTTP_X_HTTP_METHOD_OVERRIDE' in request.META: 
       request.method = request.META['HTTP_X_HTTP_METHOD_OVERRIDE'] 

      request_method = super(UserResource, self).method_check(request, allowed=allowed_methods) 
      method = getattr(self, "%s_%s" % (request_method, request_type), None) 

      if method is None: 
       raise ImmediateHttpResponse(response=HttpNotImplemented()) 

      # Authentication would normally happen here... 
      # ... simply comment it out. 
      # super(UserResource, self).is_authenticated(request) 
      super(UserResource, self).throttle_check(request) 

      # All clear. Process the request. 
      request = convert_post_to_put(request) 
      response = method(request, **kwargs) 

      # Add the throttled request. 
      super(UserResource, self).log_throttled_access(request) 

      # If what comes back isn't a ``HttpResponse``, assume that the 
      # request was accepted and that some action occurred. This also 
      # prevents Django from freaking out. 
      if not isinstance(response, HttpResponse): 
       return HttpNoContent() 

      return response 
     else: 
      return super(UserResource, self).dispatch_list(request, **kwargs) 

    # The normally required authentication is bypassed 
    # (through the overridden dispatch_list) method above. 
    def post_list(self, request, **kwargs): 
     # Process the request as usual...  
     return HttpCreated('User created.')