0

こんにちは私はthisのDjangoObjectPermissionsFilterを使用しています。DjangoObjectPermissionsをカスタマイズするには?

私はそれが私の "自己文書化" DRFのAPIに以下の記述を満たすようにclass SampleModelPermissions(permissions.DjangoObjectPermissions)を作成したい:

enter image description here

これは私のコードです:models.pyで

views.pyで
class Sample(models.Model): 
    created = models.DateTimeField(default=datetime.datetime.utcnow, blank=True, null=True) 
    last_modified = models.DateTimeField(default=datetime.datetime.utcnow, blank=True, null=True) 
    owner = models.ForeignKey(User, blank=True, null=True, related_name='sample_owner') 
    text = models.TextField(default='', blank=True, null=True) 

    class Meta: 
     permissions = (
      ('view_sample', "can view sample"), 
     ) 

    def __unicode__(self): 
     return self.text 

    def __str__(self): 
     return self.text 

permisions.py

class SampleModelPermissions(permissions.DjangoObjectPermissions): 

    perms_map = { 
     'GET': ['%(app_label)s.view_%(model_name)s'], 
     'OPTIONS': ['%(app_label)s.view_%(model_name)s'], 
     'HEAD': ['%(app_label)s.view_%(model_name)s'], 
     'POST': ['%(app_label)s.add_%(model_name)s'], 
     'PUT': ['%(app_label)s.change_%(model_name)s'], 
     'PATCH': ['%(app_label)s.change_%(model_name)s'], 
     'DELETE': ['%(app_label)s.delete_%(model_name)s'], 
    } 

    logger.info('in SampleModelPermissions') 

    def has_object_permission(self, request, view, obj): 
     logger.info('in SampleModelPermissions has_object_permission') 
     print 'permissions.SAFE_METHODS: ', permissions.SAFE_METHODS 
     if request.method in permissions.SAFE_METHODS: 
      return request.user == obj.owner or True # need to modify so can see own stuff 
     elif request.method == 'POST': 
      print 'checking if user has perm to create obj' 
      return True # request.user == obj.owner 
     elif request.method == 'PATCH': 
      return request.user == obj.owner 
     elif request.method == 'DELETE': 
      return request.user == obj.owner 
     return False 

で0

class SampleViewSet(viewsets.ModelViewSet): 
    ''' 
    * Model Description: Sample is a sample model. 
    * CRUD on Sample model 
    * C - CREATE - POST /sample/ - allowed as long as owner is the user creating the object 
    * R - READ - GET /sample/ (list) - user can see objects it owns 
    * R - READ - GET /sample/[id]/ (detail) - user can see detail page of objects it owns 
    * U - UPDATE - PATCH /sample/[id]/ - allowed for owner 
    * D - DELETE - DELETE /sample/[id]/ - allowed for owner 
    * Note in the case of a nested model A where a field f points to an instance of another model B, you can set f's value to an instance b of B by PATCHing or POSTing with f_id = [the id of b]. Yes, whenever f points to a foreign model, f is read only and f_id is write only. 
    ''' 
    queryset = Sample.objects.all() 
    filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter, DjangoObjectPermissionsFilter,) 
    permission_classes = (SampleModelPermissions,) 
    filter_fields = '__all__' 
    serializer_class = SampleSerializer 

しかし、私はPOSTMANに次を得る:私は私のAPIを取得するためにやるべきかについて

enter image description here

enter image description here

任意のヒント私は彼らが自己文書化で説明するように動作する権限を持っていますか?

答えて

0

溶液をhas_permissionGETリストとPOSTを覆い、has_object_permissionsGET細部を覆い、PATCH、及びDELETEことを認識することでした。私は自分のコードを2つの関数に分割する必要がありました(ただし、コードで他の問題を解決していますが、この問題に取り組んでいる特定の問題があります)。

class SampleModelPermissions(permissions.DjangoObjectPermissions): 

    perms_map = { 
     'GET': ['%(app_label)s.view_%(model_name)s'], 
     'OPTIONS': ['%(app_label)s.view_%(model_name)s'], 
     'HEAD': ['%(app_label)s.view_%(model_name)s'], 
     'POST': ['%(app_label)s.add_%(model_name)s'], 
     'PUT': ['%(app_label)s.change_%(model_name)s'], 
     'PATCH': ['%(app_label)s.change_%(model_name)s'], 
     'DELETE': ['%(app_label)s.delete_%(model_name)s'], 
    } 

    logger.info('in SampleModelPermissions') 

    def has_permission(self, request, view): 
     logger.info('in SampleModelPermissions has_permission') 
     if request.method in permissions.SAFE_METHODS: 
      logger.info('SampleModelPermissions: has_permission: listing samples for user: ' + str(request.user.id)) 
      return True 
     elif request.method == 'POST': 
      suggested_owner = None 
      try: 
       logger.info('SampleModelPermissions: has_permission: request dict should have a suggested owner: ' + str(dict(request.data.iterlists()))) 
       suggested_owner = int(dict(request.data.iterlists())['owner_id'][0]) 
      except: 
       logger.error('SampleModelPermissions: has_permission: request made without owner_id: ' + str(dict(request.data.iterlists()))) 
       return False 
      return request.user.id == suggested_owner 

    def has_object_permission(self, request, view, obj): 
     logger.info('in SampleModelPermissions has_object_permission') 
     print 'permissions.SAFE_METHODS: ', permissions.SAFE_METHODS 
     if request.method in permissions.SAFE_METHODS: 
      return request.user == obj.owner or True # need to modify so can see own stuff 
     elif request.method == 'PATCH': 
      return request.user == obj.owner 
     elif request.method == 'DELETE': 
      return request.user == obj.owner 
     return False 
0

ドキュメントで説明しているように、権限を管理し結果を達成する別の方法はありますか。

ほとんどの場合、オブジェクトの作成後にパーミッションを割り当てる必要があります。たとえば、権限を割り当てるためのシグナルを使用できます。

DjangoObjectPermission

class SampleModelPermissions(permissions.DjangoObjectPermissions): 

    perms_map = { 
     'GET': ['%(app_label)s.view_%(model_name)s'], 
     'OPTIONS': ['%(app_label)s.view_%(model_name)s'], 
     'HEAD': ['%(app_label)s.view_%(model_name)s'], 
     'POST': ['%(app_label)s.add_%(model_name)s'], 
     'PUT': ['%(app_label)s.change_%(model_name)s'], 
     'PATCH': ['%(app_label)s.change_%(model_name)s'], 
     'DELETE': ['%(app_label)s.delete_%(model_name)s'], 
    } 

例シグナル:

from django.db.models.signals import post_save 
from django.dispatch import receiver 
from .models import Sample 

@receiver(post_save, sender=Sample, dispatch_uid="sample_assign_permission") 
def permission_assign(sender, instance, created, **kwargs): 
    if created: 
     assign_perm('view_sample' self.request.user, instance) 
     assign_perm('change_sample', self.request.user, instance) 
     assign_perm('add_sample', self.request.user, instance) 
     assign_perm('delete_sample', self.request.user, instance) 
関連する問題