We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
REST API: project_extra with organisation filter gives duplicates
The `project_extra` REST API endpoint shows duplicate projects when it is filtered on organisation.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `akvo/rest/views/project.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 """Akvo RSR is covered by the GNU Affero General Public License.
3 
4 See more details in the license.txt file located at the root folder of the Akvo RSR module.
5 For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >.
6 """
7 
8 from akvo.rest.serializers.project import ProjectUpSerializer
9 from akvo.rsr.models import Project, PublishingStatus
10 from ..serializers import ProjectSerializer, ProjectExtraSerializer
11 from ..viewsets import BaseRSRViewSet
12 
13 
14 class ProjectViewSet(BaseRSRViewSet):
15 
16     """
17     Viewset providing Project data.
18 
19     Allowed parameters are:
20     __limit__ (default 30, max 100),
21     __title__ (exact or icontains),
22     __subtitle__ (exact or icontains),
23     __status__,
24     __language__,
25     __currency__,
26     __date_start_planned__ (exact, gt, gte, lt or lte),
27     __date_start_actual__ (exact, gt, gte, lt or lte),
28     __date_end_planned__ (exact, gt, gte, lt or lte),
29     __date_end_actual__ (exact, gt, gte, lt or lte),
30     __created_at__ (exact, gt, gte, lt or lte),
31     __last_modified_at__ (exact, gt, gte, lt or lte),
32     __sync_owner__,
33     __iati_activity_id__ (exact or icontains),
34     __hierarchy__,
35     __project_scope__,
36     __collaboration_type__,
37     __default_aid_type__,
38     __default_finance_type__,
39     __default_flow_type__,
40     __default_tied_status__,
41     __budget__ (exact, gt, gte, lt or lte),
42     __funds__ (exact, gt, gte, lt or lte),
43     __funds_needed__ (exact, gt, gte, lt or lte),
44     __categories__ (exact, in),
45     __partners__ (exact, in),
46     __keywords__ (exact, in), and
47     __publishingstatus\__status__.
48     """
49     queryset = Project.objects.select_related(
50         'publishingstatus'
51         ).prefetch_related(
52             'categories',
53             'keywords',
54             'partners')
55 
56     serializer_class = ProjectSerializer
57     filter_fields = {
58         'title': ['exact', 'icontains'],
59         'subtitle': ['exact', 'icontains'],
60         'status': ['exact', ],
61         'language': ['exact', ],
62         'currency': ['exact', ],
63         'date_start_planned': ['exact', 'gt', 'gte', 'lt', 'lte', ],
64         'date_start_actual': ['exact', 'gt', 'gte', 'lt', 'lte', ],
65         'date_end_planned': ['exact', 'gt', 'gte', 'lt', 'lte', ],
66         'date_end_actual': ['exact', 'gt', 'gte', 'lt', 'lte', ],
67         'created_at': ['exact', 'gt', 'gte', 'lt', 'lte', ],
68         'last_modified_at': ['exact', 'gt', 'gte', 'lt', 'lte', ],
69         'iati_activity_id': ['exact', 'icontains', ],
70         'hierarchy': ['exact', ],
71         'project_scope': ['exact', ],
72         'collaboration_type': ['exact', ],
73         'default_aid_type': ['exact', ],
74         'default_finance_type': ['exact', ],
75         'default_flow_type': ['exact', ],
76         'default_tied_status': ['exact', ],
77         'budget': ['exact', 'gt', 'gte', 'lt', 'lte', ],
78         'funds': ['exact', 'gt', 'gte', 'lt', 'lte', ],
79         'funds_needed': ['exact', 'gt', 'gte', 'lt', 'lte', ],
80         'categories': ['exact', 'in', ],
81         'partners': ['exact', 'in', ],
82         'keywords': ['exact', 'in', ],
83         'publishingstatus__status': ['exact', ],
84     }
85 
86     def get_queryset(self):
87         """
88         Allow custom filter for sync_owner, since this field has been replaced by the
89         reporting org partnership.
90         """
91         queryset = self.queryset
92         sync_owner = self.request.QUERY_PARAMS.get('sync_owner', None)
93         if sync_owner:
94             queryset = queryset.filter(partnerships__iati_organisation_role=101,
95                                        partnerships__organisation__pk=sync_owner)
96         return queryset
97 
98 
99 class ProjectExtraViewSet(ProjectViewSet):
100 
101     """
102     Viewset providing extra Project data.
103 
104     Allowed parameters are:
105     __limit__ (default 30, max 100),
106     __partnerships\__organisation__ (filter on organisation ID), and
107     __publishingstatus\__status__ (filter on publishing status)
108     """
109 
110     queryset = Project.objects.select_related(
111         'publishing_status').prefetch_related(
112             'sectors', 'partnerships')
113     serializer_class = ProjectExtraSerializer
114     paginate_by_param = 'limit'
115     filter_fields = ('partnerships__organisation', 'publishingstatus__status')
116 
117 
118 class ProjectUpViewSet(ProjectViewSet):
119 
120     """
121     Viewset providing extra data and limited filtering for Up in one go.
122 
123     Allowed parameters are:
124     __limit__ (default 30, max 100),
125     __partnerships\__organisation__ (filter on organisation ID), and
126     __publishingstatus\__status__ (filter on publishing status)
127     """
128 
129     queryset = Project.objects.select_related(
130         'primary_location',
131         'updates',
132         'publishingstatus'
133         ).prefetch_related(
134             'categories',
135             'keywords',
136             'partners')
137     serializer_class = ProjectUpSerializer
138     paginate_by_param = 'limit'
139     max_paginate_by = 100
140     filter_fields = ('partnerships__organisation', 'publishingstatus__status')
141
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/akvo/rest/views/project.py b/akvo/rest/views/project.py
--- a/akvo/rest/views/project.py
+++ b/akvo/rest/views/project.py
@@ -93,7 +93,7 @@
         if sync_owner:
             queryset = queryset.filter(partnerships__iati_organisation_role=101,
                                        partnerships__organisation__pk=sync_owner)
-        return queryset
+        return queryset.distinct()
 
 
 class ProjectExtraViewSet(ProjectViewSet):

{"golden_diff": "diff --git a/akvo/rest/views/project.py b/akvo/rest/views/project.py\n--- a/akvo/rest/views/project.py\n+++ b/akvo/rest/views/project.py\n@@ -93,7 +93,7 @@\n         if sync_owner:\n             queryset = queryset.filter(partnerships__iati_organisation_role=101,\n                                        partnerships__organisation__pk=sync_owner)\n-        return queryset\n+        return queryset.distinct()\n \n \n class ProjectExtraViewSet(ProjectViewSet):\n", "issue": "REST API: project_extra with organisation filter gives duplicates\nThe `project_extra` REST API endpoint shows duplicate projects when it is filtered on organisation.\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n\"\"\"Akvo RSR is covered by the GNU Affero General Public License.\n\nSee more details in the license.txt file located at the root folder of the Akvo RSR module.\nFor additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >.\n\"\"\"\n\nfrom akvo.rest.serializers.project import ProjectUpSerializer\nfrom akvo.rsr.models import Project, PublishingStatus\nfrom ..serializers import ProjectSerializer, ProjectExtraSerializer\nfrom ..viewsets import BaseRSRViewSet\n\n\nclass ProjectViewSet(BaseRSRViewSet):\n\n    \"\"\"\n    Viewset providing Project data.\n\n    Allowed parameters are:\n    __limit__ (default 30, max 100),\n    __title__ (exact or icontains),\n    __subtitle__ (exact or icontains),\n    __status__,\n    __language__,\n    __currency__,\n    __date_start_planned__ (exact, gt, gte, lt or lte),\n    __date_start_actual__ (exact, gt, gte, lt or lte),\n    __date_end_planned__ (exact, gt, gte, lt or lte),\n    __date_end_actual__ (exact, gt, gte, lt or lte),\n    __created_at__ (exact, gt, gte, lt or lte),\n    __last_modified_at__ (exact, gt, gte, lt or lte),\n    __sync_owner__,\n    __iati_activity_id__ (exact or icontains),\n    __hierarchy__,\n    __project_scope__,\n    __collaboration_type__,\n    __default_aid_type__,\n    __default_finance_type__,\n    __default_flow_type__,\n    __default_tied_status__,\n    __budget__ (exact, gt, gte, lt or lte),\n    __funds__ (exact, gt, gte, lt or lte),\n    __funds_needed__ (exact, gt, gte, lt or lte),\n    __categories__ (exact, in),\n    __partners__ (exact, in),\n    __keywords__ (exact, in), and\n    __publishingstatus\\__status__.\n    \"\"\"\n    queryset = Project.objects.select_related(\n        'publishingstatus'\n        ).prefetch_related(\n            'categories',\n            'keywords',\n            'partners')\n\n    serializer_class = ProjectSerializer\n    filter_fields = {\n        'title': ['exact', 'icontains'],\n        'subtitle': ['exact', 'icontains'],\n        'status': ['exact', ],\n        'language': ['exact', ],\n        'currency': ['exact', ],\n        'date_start_planned': ['exact', 'gt', 'gte', 'lt', 'lte', ],\n        'date_start_actual': ['exact', 'gt', 'gte', 'lt', 'lte', ],\n        'date_end_planned': ['exact', 'gt', 'gte', 'lt', 'lte', ],\n        'date_end_actual': ['exact', 'gt', 'gte', 'lt', 'lte', ],\n        'created_at': ['exact', 'gt', 'gte', 'lt', 'lte', ],\n        'last_modified_at': ['exact', 'gt', 'gte', 'lt', 'lte', ],\n        'iati_activity_id': ['exact', 'icontains', ],\n        'hierarchy': ['exact', ],\n        'project_scope': ['exact', ],\n        'collaboration_type': ['exact', ],\n        'default_aid_type': ['exact', ],\n        'default_finance_type': ['exact', ],\n        'default_flow_type': ['exact', ],\n        'default_tied_status': ['exact', ],\n        'budget': ['exact', 'gt', 'gte', 'lt', 'lte', ],\n        'funds': ['exact', 'gt', 'gte', 'lt', 'lte', ],\n        'funds_needed': ['exact', 'gt', 'gte', 'lt', 'lte', ],\n        'categories': ['exact', 'in', ],\n        'partners': ['exact', 'in', ],\n        'keywords': ['exact', 'in', ],\n        'publishingstatus__status': ['exact', ],\n    }\n\n    def get_queryset(self):\n        \"\"\"\n        Allow custom filter for sync_owner, since this field has been replaced by the\n        reporting org partnership.\n        \"\"\"\n        queryset = self.queryset\n        sync_owner = self.request.QUERY_PARAMS.get('sync_owner', None)\n        if sync_owner:\n            queryset = queryset.filter(partnerships__iati_organisation_role=101,\n                                       partnerships__organisation__pk=sync_owner)\n        return queryset\n\n\nclass ProjectExtraViewSet(ProjectViewSet):\n\n    \"\"\"\n    Viewset providing extra Project data.\n\n    Allowed parameters are:\n    __limit__ (default 30, max 100),\n    __partnerships\\__organisation__ (filter on organisation ID), and\n    __publishingstatus\\__status__ (filter on publishing status)\n    \"\"\"\n\n    queryset = Project.objects.select_related(\n        'publishing_status').prefetch_related(\n            'sectors', 'partnerships')\n    serializer_class = ProjectExtraSerializer\n    paginate_by_param = 'limit'\n    filter_fields = ('partnerships__organisation', 'publishingstatus__status')\n\n\nclass ProjectUpViewSet(ProjectViewSet):\n\n    \"\"\"\n    Viewset providing extra data and limited filtering for Up in one go.\n\n    Allowed parameters are:\n    __limit__ (default 30, max 100),\n    __partnerships\\__organisation__ (filter on organisation ID), and\n    __publishingstatus\\__status__ (filter on publishing status)\n    \"\"\"\n\n    queryset = Project.objects.select_related(\n        'primary_location',\n        'updates',\n        'publishingstatus'\n        ).prefetch_related(\n            'categories',\n            'keywords',\n            'partners')\n    serializer_class = ProjectUpSerializer\n    paginate_by_param = 'limit'\n    max_paginate_by = 100\n    filter_fields = ('partnerships__organisation', 'publishingstatus__status')\n", "path": "akvo/rest/views/project.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n\"\"\"Akvo RSR is covered by the GNU Affero General Public License.\n\nSee more details in the license.txt file located at the root folder of the Akvo RSR module.\nFor additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >.\n\"\"\"\n\nfrom akvo.rest.serializers.project import ProjectUpSerializer\nfrom akvo.rsr.models import Project, PublishingStatus\nfrom ..serializers import ProjectSerializer, ProjectExtraSerializer\nfrom ..viewsets import BaseRSRViewSet\n\n\nclass ProjectViewSet(BaseRSRViewSet):\n\n    \"\"\"\n    Viewset providing Project data.\n\n    Allowed parameters are:\n    __limit__ (default 30, max 100),\n    __title__ (exact or icontains),\n    __subtitle__ (exact or icontains),\n    __status__,\n    __language__,\n    __currency__,\n    __date_start_planned__ (exact, gt, gte, lt or lte),\n    __date_start_actual__ (exact, gt, gte, lt or lte),\n    __date_end_planned__ (exact, gt, gte, lt or lte),\n    __date_end_actual__ (exact, gt, gte, lt or lte),\n    __created_at__ (exact, gt, gte, lt or lte),\n    __last_modified_at__ (exact, gt, gte, lt or lte),\n    __sync_owner__,\n    __iati_activity_id__ (exact or icontains),\n    __hierarchy__,\n    __project_scope__,\n    __collaboration_type__,\n    __default_aid_type__,\n    __default_finance_type__,\n    __default_flow_type__,\n    __default_tied_status__,\n    __budget__ (exact, gt, gte, lt or lte),\n    __funds__ (exact, gt, gte, lt or lte),\n    __funds_needed__ (exact, gt, gte, lt or lte),\n    __categories__ (exact, in),\n    __partners__ (exact, in),\n    __keywords__ (exact, in), and\n    __publishingstatus\\__status__.\n    \"\"\"\n    queryset = Project.objects.select_related(\n        'publishingstatus'\n        ).prefetch_related(\n            'categories',\n            'keywords',\n            'partners')\n\n    serializer_class = ProjectSerializer\n    filter_fields = {\n        'title': ['exact', 'icontains'],\n        'subtitle': ['exact', 'icontains'],\n        'status': ['exact', ],\n        'language': ['exact', ],\n        'currency': ['exact', ],\n        'date_start_planned': ['exact', 'gt', 'gte', 'lt', 'lte', ],\n        'date_start_actual': ['exact', 'gt', 'gte', 'lt', 'lte', ],\n        'date_end_planned': ['exact', 'gt', 'gte', 'lt', 'lte', ],\n        'date_end_actual': ['exact', 'gt', 'gte', 'lt', 'lte', ],\n        'created_at': ['exact', 'gt', 'gte', 'lt', 'lte', ],\n        'last_modified_at': ['exact', 'gt', 'gte', 'lt', 'lte', ],\n        'iati_activity_id': ['exact', 'icontains', ],\n        'hierarchy': ['exact', ],\n        'project_scope': ['exact', ],\n        'collaboration_type': ['exact', ],\n        'default_aid_type': ['exact', ],\n        'default_finance_type': ['exact', ],\n        'default_flow_type': ['exact', ],\n        'default_tied_status': ['exact', ],\n        'budget': ['exact', 'gt', 'gte', 'lt', 'lte', ],\n        'funds': ['exact', 'gt', 'gte', 'lt', 'lte', ],\n        'funds_needed': ['exact', 'gt', 'gte', 'lt', 'lte', ],\n        'categories': ['exact', 'in', ],\n        'partners': ['exact', 'in', ],\n        'keywords': ['exact', 'in', ],\n        'publishingstatus__status': ['exact', ],\n    }\n\n    def get_queryset(self):\n        \"\"\"\n        Allow custom filter for sync_owner, since this field has been replaced by the\n        reporting org partnership.\n        \"\"\"\n        queryset = self.queryset\n        sync_owner = self.request.QUERY_PARAMS.get('sync_owner', None)\n        if sync_owner:\n            queryset = queryset.filter(partnerships__iati_organisation_role=101,\n                                       partnerships__organisation__pk=sync_owner)\n        return queryset.distinct()\n\n\nclass ProjectExtraViewSet(ProjectViewSet):\n\n    \"\"\"\n    Viewset providing extra Project data.\n\n    Allowed parameters are:\n    __limit__ (default 30, max 100),\n    __partnerships\\__organisation__ (filter on organisation ID), and\n    __publishingstatus\\__status__ (filter on publishing status)\n    \"\"\"\n\n    queryset = Project.objects.select_related(\n        'publishing_status').prefetch_related(\n            'sectors', 'partnerships')\n    serializer_class = ProjectExtraSerializer\n    paginate_by_param = 'limit'\n    filter_fields = ('partnerships__organisation', 'publishingstatus__status')\n\n\nclass ProjectUpViewSet(ProjectViewSet):\n\n    \"\"\"\n    Viewset providing extra data and limited filtering for Up in one go.\n\n    Allowed parameters are:\n    __limit__ (default 30, max 100),\n    __partnerships\\__organisation__ (filter on organisation ID), and\n    __publishingstatus\\__status__ (filter on publishing status)\n    \"\"\"\n\n    queryset = Project.objects.select_related(\n        'primary_location',\n        'updates',\n        'publishingstatus'\n        ).prefetch_related(\n            'categories',\n            'keywords',\n            'partners')\n    serializer_class = ProjectUpSerializer\n    paginate_by_param = 'limit'\n    max_paginate_by = 100\n    filter_fields = ('partnerships__organisation', 'publishingstatus__status')\n", "path": "akvo/rest/views/project.py"}]}