TastyPie-如何仅授权通过外国钥匙更新模型



a具有许多模型中的位置模型。不希望用户能够直接创建,编辑或删除位置(使用/api/v1/location/endpoint),但我希望他们能够做到的是创建具有其位置作为其外国的对象时钥匙。例如:

/api/v1/event/
{
    "name": "xxx",
    "location": {
       <new location>
    }
}

可能吗?

我认为合理的解决方案是为同一模型拥有2个单独的资源。一个用作独立资源,第二个用作事件内部的参考,两者都具有不同的授权规则。

class LocationLimitedResource(ModelResource):
    # ...
    class Meta:
        serializer = Serializer(formats=['json'])
        queryset = Location.objects.all()
        resource_name = 'location_limited'
        allowed_methods = ['get']
        always_return_data = True
        authentication = ApiKeyAuthentication()
        authorization = LocationAuthorization()
        # ...

class LocationResource(LocationLimitedResource):
    class Meta(LocationLimitedResource.Meta):
        allowed_methods = ['get', 'post', 'put', 'delete']
        resource_name = 'location'

class EventResource(ModelResource):
    location = fields.ForeignKey(LocationResource, 'location', full=True)
    class Meta:
        serializer = Serializer(formats=['json'])
        queryset = Event.objects.all()
        resource_name = 'event'
        allowed_methods = ['get', 'post']
        always_return_data = True
        authentication = ApiKeyAuthentication()
        authorization = EventAuthorization()
jobs_api = Api(api_name='v1')
jobs_api.register(LocationLimitedResource())
jobs_api.register(LocationResource())
jobs_api.register(EventResource())

另一种我不喜欢的方式,因为它有点黑,是:

class LocationAuthorization(Authorization):
    # [...]
    def create_detail(self, object_list, bundle):
        return '/api/v1/event/' == bundle.request.path:
    # [...]

class LocationResource():
    # [...]
    class Meta:
        serializer = Serializer(formats=['json'])
        queryset = Location.objects.all()
        resource_name = 'location'
        authorization = LocationAuthorization()
        # [...]

当然,它义务您要硬编码您喜欢允许/禁止访问的资源的路径。一段时间后,您可以忘记该规则是自然而然的。同样,对于API的文档和自我发现也很难。

最新更新