我正在试验Tastypie和Django,我想知道我能做什么是可能的。让我解释一下......
我有一个自定义用户资源(和模型)作为我的api的一部分。我希望能够通过此资源更新用户。为确保用户只能由其所有者进行更新,我已启用tastypie.authentication.BasicAuthentication
(这是通过put_detail
方法完成的。)
问题在于我还希望能够通过此资源创建用户,由于您需要登录凭据才能访问BasicAuthentication
,因此无法完成此操作。
所以,我觉得我有以下几种选择:
user
。理想情况下,我希望将第二个资源命名为user/create
,但网址永远无法正确解析,因为user
模型已将其取消。这是我用第二种方法尝试过的......
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
发帖,则CreateUserResource
永远不会对其进行处理,因为tastypie会将其解释为UsersResource
的详细视图,然后我会获得404。
那么,是否有可能改变tastypie搜索其资源网址的顺序?在我的urls.py
文件中注册资源的顺序似乎没有什么区别。或者是否有其他建议可能更适合我想要实施的内容?
答案 0 :(得分:0)
好的,我设法通过覆盖dispatch
模型的UserResource
方法,使用方法编号1来完成此操作。来自文档[link]:
dispatch
做了一堆繁重的工作。它确保:
- 请求的HTTP方法位于allowed_methods(
method_check
),- 该类有一个方法可以处理请求(
get_list
),- 用户已通过身份验证(
is_authenticated
),- 用户已获得授权(
is_authorized
),- &安培;用户没有超过他们的油门(
throttle_check
)。此时,dispatch实际调用所请求的方法 (
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.')