title: django rest framework filter on related model
body: <p>I have a model countries and a model of persons on holiday in a certain year to a country. I want to have an Api of Countries in which I can filter only the countries in which certain persons had a holiday in a certain year.</p>
  
  <p>Models.py</p>
  
  <pre><code>from django.db import models
  
  class Country(models.Model):
    id = models.CharField(max_length=50,primary_key=True)
    country = models.CharField(max_length=255,null=True)
  
  class PersonYear(models.Model):
    id = models.IntegerField(primary_key=True)
    person = models.CharField(max_length=255,null=True)
    year = models.IntegerField(null=True)
    country = models.ForeignKey(Country, related_name='personyears')
  </code></pre>
  
  <p>Contents of model Country</p>
  
  <pre><code>id|country
  1|France
  2|Italy
  3|Spain
  </code></pre>
  
  <p>Contents of model PersonYear</p>
  
  <pre><code>id|person|year|country_id
  1|John|2014|1
  2|John|2015|1
  3|Mary|2014|1
  </code></pre>
  
  <p>serializers.py</p>
  
  <pre><code>from apiapp.models import PersonYear,Country
  from rest_framework import serializers
  
  class PersonyearSerializer(serializers.HyperlinkedModelSerializer):
  
     class Meta:
        model = PersonYear
        fields = ('id','person','year')
  
  class CountrySerializer(serializers.HyperlinkedModelSerializer):
     personyears = PersonyearSerializer(many=True)
  
     class Meta:
        model = Country
        fields = ('id','country','personyears')
  </code></pre>
  
  <p>Views.py</p>
  
  <pre><code>import rest_framework_filters as filters
  
  class PersonyearFilter(filters.FilterSet):
     id = filters.AllLookupsFilter(name='id')
     person = filters.AllLookupsFilter(name='person')
     year = filters.AllLookupsFilter(name='year')
  
     class Meta:
        model = PersonYear
  
  class PersonyearViewSet(viewsets.ModelViewSet):
     queryset = PersonYear.objects.all()
     serializer_class = PersonyearSerializer
     filter_backends = (filters.backends.DjangoFilterBackend,)
     filter_fields =  ['id','person','year']
     filter_class = PersonyearFilter
  
  class CountryFilter(filters.FilterSet):
     id = filters.AllLookupsFilter(name='id')
     nm = filters.AllLookupsFilter(name='country')
     personyears = filters.RelatedFilter(PersonyearFilter,name='personyears') 
  
     class Meta:
        model = Country 
  
  class CountryViewSet(viewsets.ModelViewSet):
     queryset = Country.objects.all()
     serializer_class = CountrySerializer
     filter_backends = (filters.backends.DjangoFilterBackend,)
     filter_fields = ['id','country','personyears']
     filter_class = CountryFilter
  </code></pre>
  
  <p>I want a selection of all countries in which John had a holiday in 2014:</p>
  
  <p><a href="http://localhost:8000/country/?personyears__person=John&amp;personyears__year=2014" rel="nofollow">http://localhost:8000/country/?personyears__person=John&amp;personyears__year=2014</a></p>
  
  <p>I expected to get one record:</p>
  
  <pre><code>{"id": "1", "country": "France",
     "personyears": [
      {   "id": 1,
          "person": "John"
          "year": 2014
      }
  ]
  }
  </code></pre>
  
  <p>But instead I got this record repeated 4 times. Can you explain what I am doing wrong and how to get what I want.</p>
  
  <p>Update1: </p>
  
  <p>I don't want only a special solution for John in 2014. I want a solution for all instances of Anyperson in AnyYear. For example I also want the following filter to give me one result:
  <a href="http://localhost:8001/api/country/?personyears__person=Mary&amp;personyears__year=2014" rel="nofollow">http://localhost:8001/api/country/?personyears__person=Mary&amp;personyears__year=2014</a></p>
  
  <p>Update2:</p>
  
  <p>I tried replacing:</p>
  
  <pre><code> queryset = Country.objects.all()
  </code></pre>
  
  <p>by:</p>
  
  <pre><code> queryset = Country.objects.all().distinct()
  </code></pre>
  
  <p>It helped to get the expected (1 record) outcome of:</p>
  
  <p>localhost:8000/country/?personyears__person=John&amp;personyears__year=2014</p>
  
  <p>But I now get unexpected/unwanted result for person='Mary' / year='2015'</p>
  
  <p>localhost:8000/country/?personyears__person=Mary&amp;personyears__year=2015</p>
  
  <p>I expected no result (Mary did not go on holiday in 2015 to any country). But I got</p>
  
  <pre><code>  {"id": "1","country": "France",
     "personyears": [
              {
                  "id": 1,
                  "person": "John",
                  "year": 2014
              },
              {
                  "id": 2,
                  "person": "John",
                  "year": 2015
              },
              {
                  "id": 3,
                  "person": "Mary",
                  "year": 2014
              }
     ]
     }
  </code></pre>