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.