Skip to content

Field-Level Permissions

Often, depending on the user, not all fields should be visible or only a subset should be writable.

For these scenarios, you can define a scope_fields method on the access policy which is passed the dict of name:Field pairs from a serializer used with the FieldAccessMixin.

Scenario: A field should only exist for admin users

Requirement: When a customer account is serialized or deserialized, the email field should only be present if the user is an admin.

You could define a scope_fields method on the access policy like this:

class CustomerAccountAccessPolicy(AccessPolicy):
    statements = [
      # statements that define who is allowed to perform what action
    ]

    @classmethod
    def scope_fields(cls, request, fields: dict, instance=None) -> dict:
        if not request.user.is_admin():
            fields.pop('email', None)
        return fields

Make sure to add the FieldAccessMixin to your serializer and assign it the correct access policy in its Meta class:

from rest_access_policy import FieldAccessMixin


class CustomerAccountSerializer(FieldAccessMixin, serializers.ModelSerializer):
    class Meta:
        model = UserAccount
        fields = ["username", "first_name", "last_name", "email"]
        access_policy = CustomerAccountAccessPolicy

Scenario: A field should be read-only, except for the author

Requirement: When a request is made to update an article, the content field should be read-only, except for the author.

You could define a scope_fields method on the access policy like this:

class CustomerAccountAccessPolicy(AccessPolicy):
    statements = [
      # statements that define who is allowed to perform what action
    ]

    @classmethod
    def scope_fields(cls, request, fields: dict, instance=None) -> dict:
        if instance and instance.author != request.user:
            fields["content"].read_only = True
        return fields

As before, make sure to add the FieldAccessMixin to your serializer and assign it the correct access policy in its Meta class.