Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I apply a filter to a nested resource in Django REST framework?

In my app I have the following models:

class Zone(models.Model):     name = models.SlugField()  class ZonePermission(models.Model):     zone = models.ForeignKey('Zone')     user = models.ForeignKey(User)     is_administrator = models.BooleanField()     is_active = models.BooleanField() 

I am using Django REST framework to create a resource that returns zone details plus a nested resource showing the authenticated user's permissions for that zone. The output should be something like this:

{     "name": "test",      "current_user_zone_permission": {         "is_administrator": true,          "is_active": true     } }  

I've created serializers like so:

class ZonePermissionSerializer(serializers.ModelSerializer):     class Meta:         model = ZonePermission         fields = ('is_administrator', 'is_active')  class ZoneSerializer(serializers.HyperlinkedModelSerializer):     current_user_zone_permission = ZonePermissionSerializer(source='zonepermission_set')      class Meta:         model = Zone         fields = ('name', 'current_user_zone_permission') 

The problem with this is that when I request a particular zone, the nested resource returns the ZonePermission records for all the users with permissions for that zone. Is there any way of applying a filter on request.user to the nested resource?

BTW I don't want to use a HyperlinkedIdentityField for this (to minimise http requests).

Solution

This is the solution I implemented based on the answer below. I added the following code to my serializer class:

current_user_zone_permission = serializers.SerializerMethodField('get_user_zone_permission')  def get_user_zone_permission(self, obj):     user = self.context['request'].user     zone_permission = ZonePermission.objects.get(zone=obj, user=user)     serializer = ZonePermissionSerializer(zone_permission)     return serializer.data 

Thanks very much for the solution!

like image 751
David Jones - iPushPull Avatar asked May 29 '13 18:05

David Jones - iPushPull


People also ask

How do I filter Queryset in Django REST framework?

The simplest way to filter the queryset of any view that subclasses GenericAPIView is to override the . get_queryset() method. Overriding this method allows you to customize the queryset returned by the view in a number of different ways.

What is the purpose of filter () method in Django?

The filter() method is used to filter you search, and allows you to return only the rows that matches the search term.


1 Answers

I'm faced with the same scenario. The best solution that I've found is to use a SerializerMethodField and have that method query and return the desired values. You can have access to request.user in that method through self.context['request'].user.

Still, this seems like a bit of a hack. I'm fairly new to DRF, so maybe someone with more experience can chime in.

like image 83
user2437225 Avatar answered Sep 22 '22 21:09

user2437225