22👍
✅
Ouch, that was easier than I thought:
class CustomDjangoModelPermission(permissions.DjangoModelPermissions):
def __init__(self):
self.perms_map = copy.deepcopy(self.perms_map) # from EunChong's answer
self.perms_map['GET'] = ['%(app_label)s.view_%(model_name)s']
10👍
@Yannic Hamann’s solution has a small bug. It overwrites parent’s perms_map[‘GET’].
As follows, A dictionary overring need deepcopy.
class CustomDjangoModelPermission(permissions.DjangoModelPermissions):
def __init__(self):
self.perms_map = copy.deepcopy(self.perms_map) # you need deepcopy when you inherit a dictionary type
self.perms_map['GET'] = ['%(app_label)s.view_%(model_name)s']
dictionary overring test
class Parent:
perms = {'GET':'I am a Parent !'}
class Child(Parent):
def __init__(self):
self.perms['GET'] = 'I am a Child !'
dictionary overring result
>>> print(Parent().perms['GET'])
I am a Parent !
>>> print(Child().perms['GET'])
I am a Child !
>>> print(Parent().perms['GET'])
I am a Child ! # Parent's perms is overwritten by Child.
^^^^^
2👍
You have to override the custome DjangoModelPermissions.
class BaseModelPerm(permissions.DjangoModelPermissions):
def get_custom_perms(self, method, view):
app_name = view.model._meta.app_label
return [app_name+"."+perms for perms in view.extra_perms_map.get(method, [])]
def has_permission(self, request, view):
perms = self.get_required_permissions(request.method, view.model)
perms.extend(self.get_custom_perms(request.method, view))
return (
request.user and
(request.user.is_authenticated() or not self.authenticated_users_only) and
request.user.has_perms(perms)
)
in the view you can use like below
class ViewName(generic.ListApiView):
""" Trip listing view """
model = model_name
serializer_class = serializer_class
permission_classes = (permissions.IsAuthenticated,BaseModelPerm)
queryset = model.objects.all()
extra_perms_map = {
'GET': ["can_view_trip"],
}
add the whatever extra permissions you want to add.
0👍
Following @Yannic Hamann’s solution by design the developer should not call the init method instead it is called by Python when an instance of the class is created,
for scalability, you can add new permission to the dictionary in your custom model permission
class CustomModelPermissions(permissions.DjangoModelPermissions):
"""
Custom ModelPermissions:
-This permission must only be applied to views that have a .queryset property or get_queryset() method
-Authorization will only be granted if the user is authenticated and has the relevant model permissions assigned
"""
def get_required_permissions(self, method, model_cls):
"Use append to add more action to GET,POST,PUT,PATCH As in"
"""
self.perms_map['GET'].append('%(app_label)s.view_%(model_name)s'), THIS IS TO ENSURE YOU DO NOT OVERIDE THE EXISING METHOD permmsions
"""
self.perms_map["GET"].append("%(app_label)s.view_%(model_name)s")
return super().get_required_permissions(method, model_cls)
- Django logging requests
- Error Logging in Django and Gunicorn
- How to run Django with Uvicorn webserver?
Source:stackexchange.com