How to handle 3 levels of field permission in Django REST framework
I am building Django REST as backend and Angular JS as frontend.
Now I have permission systems very advanced like 3 levels
class UserSerializer(serializers.Serializer):
email = serializers.EmailField()
username = serializers.CharField(max_length=100)
field1 = serializers.CharField(max_length=100)
field2 = serializers.CharField(max_length=100)
field3 = serializers.CharField(max_length=100)
field4 = serializers.CharField(max_length=100)
Now you want permission to
User Role
view
READ / Write / Update /Delete
There are 10 roles, 30 views for example /user/view1
/user/view2
and then READ or write as
They are on field level permissions like
Field1 can be READ by Manager level on view 1
Field1 can be Edit by Manager level on view 2
Feild1 can be Delete by Admin on View 1
I am confused how can I get a permission model like this.
source to share
I usually recommend different serializer classes for these cases, but this limits read and write permissions (sort of) and may not suit your needs.
You must create a serializer for each permission level. Let's say there are three permission levels: Admin, Manager, Normal User.
class NormalUserSerializer(ModelSerializer):
email = serializers.EmailField(read_only=True, required=True)
username = serializers.CharField(max_length=100, read_only=True)
class Meta:
fields = ("email", "username", )
class ManagerUserSerializer(NormalUserSerializer):
email = serializers.EmailField(read_only=False, required=True)
username = serializers.CharField(max_length=100, read_only=False)
class AdminSerializer(ManagerUserSerializer):
email = serializers.EmailField(read_only=False, required=False)
username = serializers.CharField(max_length=100, read_only=False)
This will restrict regular users to read-only data presentation ( read_only
DRF applied). For managers, they have the ability to read and write to the fields, but they cannot clear the contents of the field email
(compliance required
). Admins have the ability to read and write to all fields, as well as clear the contents of the field email
.
Your view will then return the correct serializer class get_serializer_class
based on the role of the authenticated user.
class UserViewSet(ModelViewSet):
def get_serializer_class(self):
if self.request.user.is_superuser:
return AdminUserSerializer
if self.request.user.is_staff:
return ManagerUserSerializer
return NormalUserSerializer
Another option is to force everything in your method validate
and manually remove the fields in the method to_native
in the serializer. If you can live with creating a serializer for each role, this is the simplest and (arguably) cleanest way to implement role-based permissions for individual fields in the Django REST Framework.
source to share
I have the same problem with a client. I created django-rest-framework-roles to automatically parameterize a given DRF method (ex: get_queryset, get_serializer_class) by user type. This way, you don't have to repeatedly print conditional blocks over user types.
I would like to extend the library to handle the more complex permission problems you describe. I have the same problems, for example: parameterization by HTTP and HTTP verb.
source to share