You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
My ViewSet doesn't have access to my Model classes (my serializers included!).
To use this lib I'm going to overwrite the methods DRYPermissions.has_permission and DRYPermissions.has_object_permission to use my service instead of model_class and obj respectively.
My code
fromrest_frameworkimportpermissionsfromdry_rest_permissions.genericsimportDRYPermissionsfrom ..rest_framework.viewsetsimportServiceGenericViewSetclassServiceDRYPermissions(DRYPermissions):
""" Customização para o DRYPermissions utilizar a nossa camada service, e não o model! """defhas_permission(self, request, view: ServiceGenericViewSet):
""" Overrides the standard function and figures out methods to call for global permissions. """ifnotself.global_permissions:
returnTrueassertview.serviceisnotNone, (
"global_permissions set to true without a service ""set on the view for '%s'"%view.__class__.__name__
)
service=view.get_service()
action_method_name=Noneifhasattr(view, 'action'):
action=self._get_action(view.action)
action_method_name="has_{action}_permission".format(action=action)
# If the specific action permission exists then use it, otherwise use general.ifhasattr(service, action_method_name):
returngetattr(service, action_method_name)(request=request)
ifrequest.methodinpermissions.SAFE_METHODS:
asserthasattr(service, 'has_read_permission'), \
self._get_error_message(service, 'has_read_permission', action_method_name)
returnservice.has_read_permission(request=request)
else:
asserthasattr(service, 'has_write_permission'), \
self._get_error_message(service, 'has_write_permission', action_method_name)
returnservice.has_write_permission(request=request)
defhas_object_permission(self, request, view: ServiceGenericViewSet, obj):
""" Overrides the standard function and figures out methods to call for object permissions. """ifnotself.object_permissions:
returnTrueservice=view.get_service()
action_method_name=Noneifhasattr(view, 'action'):
action=self._get_action(view.action)
action_method_name="has_object_{action}_permission".format(action=action)
# If the specific action permission exists then use it, otherwise use general.ifhasattr(service, action_method_name):
returngetattr(service, action_method_name)(request=request, obj=obj)
ifrequest.methodinpermissions.SAFE_METHODS:
asserthasattr(service, 'has_object_read_permission'), \
self._get_error_message(service, 'has_object_read_permission', action_method_name)
returnservice.has_object_read_permission(request=request, obj=obj)
else:
asserthasattr(service, 'has_object_write_permission'), \
self._get_error_message(service, 'has_object_write_permission', action_method_name)
returnservice.has_object_write_permission(request=request, obj=obj)
Proposition
Instead of doing
serializer_class=view.get_serializer_class()
assertserializer_class.Meta.modelisnotNone, (
"global_permissions set to true without a model ""set on the serializer for '%s'"%view.__class__.__name__
)
model_class=serializer_class.Meta.model
I suggest to create a function to get the 'target' for the permission loookup!
Suggestion of overwritable helper function
classDRYPermissions(permissions.BasePermission):
def_get_permission_target(self,view, obj=None):
ifobj:
returnobjserializer_class=view.get_serializer_class()
assertserializer_class.Meta.modelisnotNone, (
"global_permissions set to true without a model ""set on the serializer for '%s'"%view.__class__.__name__
)
model_class=serializer_class.Meta.modelreturnmodel_class
This way I could overwrite only the target without duplicating the whole lib!
Another improvement possible is to use **kwargs!
This way anyone who uses this lib may 'ignore' the arguments passed if they don't want it.
Thanks for all the details and links, it's a really interessting concept and integration. Honestly i do not see why to refuse a PR on this subject, it seems to be to be a really good enhancement to allow new architecture.
If you do so, please think about:
updating the documentation to make a little example with your architecture
update test to be sure we keep it working in the future since other contributor will maybe not know your kind of architecture
I will make sure to follow this thread and to help you if you need help with your PR, we will be able to make a release as soon as it will be merged to not let you wait after it.
I'm willing to open PR!
Resume
I'm not using Django/DRF in a traditional way. I'm using a Domain Driven Design architecture.
My ViewSet doesn't have access to my Model classes (my serializers included!).
To use this lib I'm going to overwrite the methods
DRYPermissions.has_permission
andDRYPermissions.has_object_permission
to use myservice
instead ofmodel_class
andobj
respectively.My code
Proposition
Instead of doing
I suggest to create a function to get the 'target' for the permission loookup!
Suggestion of overwritable helper function
This way I could overwrite only the target without duplicating the whole lib!
Another improvement possible is to use **kwargs!
This way anyone who uses this lib may 'ignore' the arguments passed if they don't want it.
permission call
obj permission call
The text was updated successfully, but these errors were encountered: