Search code examples
pythondjangodjango-rest-frameworkdjango-filter

Django filter all assigned foreing keys


Hello I would like to ask how to filter all assigned ForeignKeys of the object. My models looks like:

class Person(models.Model):
    name =  models.CharField(max_length=250)

class VirtualProject(models.Model):
    project_name = models.CharField(max_length=250)
    owner = models.ForeignKey(Person)

class Hours(models.Model):
    hours = models.FloatField()
    assigned_virtual_project = ForeignKey(VirtualProject)
    date = models.DateField()

I am sending GET request with owner and dateRange parameters and I would like to filter all virtual projects assigned to the owner (this is no issue, I can get this) AND also get all hours objects assigned to the virtual projects and sum all hours in specified date range. How I can do that? For frontend I am using React, so I am using django rest framework. What I got so far in views:

class GetDataView(viewsets.ModelViewSet):
    serializer_class = DataSerializer
    
    def get_queryset(self):
       owner = self.request.query_params.get('owner')
       dateRange = self.request.query_params.get('dateRange')

       queryset = VirtualProject.objects.filter(owner=owner)
       return queryset

EDIT:

Serializers.py:

class VirtualProjectSerializer(serializers.ModelSerializer):
         class Meta:
             model = VirtualProject
             fields = '__all__'

Solution

  • You can simply use a SerializerMethodField in your serializer, associated with a sum aggregate query.

    from django.db.models import Sum
    from models import Hours
    
    class VirtualProjectSerializer(serializers.ModelSerializer):
             hours = serializers.SerializerMethodField()
    
             class Meta:
                 model = VirtualProject
                 fields = '__all__'
    
             def get_hours(self, obj):
                 qs = Hours.objects.filter(assigned_virtual_project=obj).aggregate(Sum(hours))
                 return qs
          
    

    Note that this will be read-only, which I believe is what you want anyway.