【问题标题】:Tastypie - How to only authorize update a model through foreign keys?Tastypie - 如何仅授权通过外键更新模型?
【发布时间】:2017-11-27 13:15:54
【问题描述】:

A 有一个 Location 模型,它在许多模型中都是外键。不希望用户能够直接创建、编辑或删除位置(使用 /api/v1/location/ 端点),但我希望他们能够在创建一个将位置作为其外部对象的对象时钥匙。 例如:

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

有可能吗?

【问题讨论】:

    标签: python django api tastypie


    【解决方案1】:

    我认为合理的解决方案是为同一模型设置 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 的文档和自我发现也更加困难。

    【讨论】:

      猜你喜欢
      • 2021-10-23
      • 2018-06-13
      • 2013-07-18
      • 1970-01-01
      • 1970-01-01
      • 2021-03-21
      • 1970-01-01
      • 2014-01-13
      • 2013-10-14
      相关资源
      最近更新 更多