Sometimes, I want data in my serialized data that's specific to the user who's logged in. What if there's a data feed and I want to know if a user favorited a specific story upon retrieving that story's info in their client? What if a user logs in and only wants to see unread stories in their feed as opposed to the entire feed?
I have a user-agnostic set of data: data that has nothing to do with the user viewing the site. I want to make that data somewhat personal by adding attributes (fields) to the data that suit an authenticated (logged-in) user.
Django REST framework easily allows me to serialize the data model. The serialized data has fields corresponding with data model fields.
How can I load data specific to a user who's logged in inside of the serialized, loaded data?
class Story(models.Model): title = models.CharField(max_length="255") body = models.TextField() class Favorite(models.Model): story = models.ForeignKey(Story, related_name="favorites") user = models.ForeignKey(settings.AUTH_USER_MODEL)
class StorySerializer(serializers.Serializer): title = serialzers.CharField() body = serializers.TextField() is_favorite = serializers.SerializerMethodField('has_favorited_story') class Meta: model = Story fields = ('id', 'title', 'is_favorite',) def has_favorited_story(self, obj): """Check for whether the visiting user fav'd the story. """ user = self.context['request'].user s = obj # the story object user_has_favorited = False # False by default try: user_has_favorited = bool(Favorite.objects.filter(user=user.id, story=story.id)) except Exception, e: raise user_has_favorited return user_has_favorited
In order to get the logged-in user data, we're taking advantage of our Serializer class coming with a
context dictionary containing
request, leading us to our
user object, which contains attributes of an authenticated user if someone is logged in. In this case, we're checking to see if there's a
Favorite object stored in our database linked to both the story object and the authenticated user.
Here, we're using the
SerializerMethodField which points to our serializer method called
has_favorited_story. Our method takes one parameter (aside from
self, of course): the
obj, which represents a story object in this case. Since
Story attributes, we can grab data specific to one story (the story passed to our serializer method).
If there's a cleaner, better way to do this, just let me know. I wrote it this way just to get the job done and it works.
I miss you so much, Renee.