Reputation: 1533
I'm not overly familiar with DRF or Django, but here goes:
I'm working on a workout-API that returns a user, and the user is able to set the visibility of their profile. The table looks something like:
id | username | email | coach_id | visibility
where visibility
is one of public
, coach
, private
.
This means that if User 1
has visibility = private
, another user fetching their profile should only see the attributes id
and username
, but the user themselves should get all the attributes.
The user's coach should see a profile if visibility = public
or visibility = coach
.
I've looked into dynamically setting the serializer's fields
-variable, with no luck (because the fields should be "generated" depending on the content of the object/instance).
I've also looked into extra_field = serializers.SerializerMethodField()
, but that resulted in all the values being shown as sub-properties of extra_field
.
What I am wondering is: What is the best way to attack this problem?
Upvotes: 1
Views: 653
Reputation: 1533
I solved it!
I used the to_representation
-function in my serializer like so:
class VisibilityAwareUserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = get_user_model()
fields = [
"id",
"username",
"visibility",
"email",
"coach",
]
def to_representation(self, instance):
ret = super(PermissionAwareUserSerializer, self).to_representation(instance)
fields_to_pop = [
"email",
"coach",
]
if not self.userCanSeeObject(self.context['request'].user, instance):
[ret.pop(field,'') for field in fields_to_pop]
return ret
def userCanSeeObject(self, user, obj):
return ((obj.visibility == "public") or (obj.visibility == "coach" and obj.coach == user or obj == user) or (obj.visibility == "private" and obj == user))
Feel free to point out weaknesses in this solution, but it seems to work well for me.
Upvotes: 2