Tastypie - 如何仅通过外键授权更新模型?

时间:2017-11-27 13:15:54

标签: python django api tastypie

A有一个位置模型,它是许多模型中的外键。不希望用户能够直接创建,编辑或删除位置(使用/ api / v1 / location / endpoint),但我希望他们能够创建一个具有Location的对象它的外键。 例如:

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

有可能吗?

1 个答案:

答案 0 :(得分:0)

我认为合理的解决方案是为同一模型提供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的记录和自我发现也更难。