Search code examples
djangopython-3.xdjango-rest-frameworkdjango-querysetdjango-rest-viewsets

Error creating merged queries with Q() and filter() in a viewset with djangoORM


I am trying to create a filter with multiple elements in a queryset for a MOdelViewSet. I am overwriting the get_queryset method to fetch the results according to a user role.

I am using Q() and works perfectly when i try to a single filter, for example:

 Cohort.objects.filter(Q(mode="p") )

or this:

 Cohort.objects.filter(Q(participant__user__id=self.request.user.id))

Both works perfectly filtering the queryset, but when i combine then as this...

Cohort.objects.filter(
                Q(participant__user__id=self.request.user.id) |
                Q(mode="p")
           )

The queryset multiply the number of registries and bring to many results, repeated results, to the point that the request fails.

This is the complete method:

    def get_queryset(self):
        user_role = self.request.user.rol

        if user_role == '0':
            base_qs=Cohort.objects.all()
        elif user_role == '1':
            base_qs=Cohort.objects.filter(
                Q(participant__user__id=user.id)
            )
        elif user_role == '2':
            base_qs = Cohort.objects.filter(
                Q(participant__user__id=self.request.user.id) |
                Q(mode="p")
            )

        scope = self.request.query_params.get('isNext', None)

        if scope is None:
            return base_qs
        elif scope:
            return base_qs.filter(fecha_final > datetime.date.today())
        return base_qs.filter(fecha_final < datetime.date.today())

I don not recieve any error messages. checking the documentation this is the way to use Q but something is happening. What am i doing wrong? I am using

Django==2.2.4

djangorestframework==3.10.2


Solution

  • as Ben sugested, the solution was to use the distinct() method to avoid the duplicated results. So the final queryset worked as this:

     base_qs=Cohort.objects.filter(
                Q(participant__user__id=self.request.user.id) |
                Q(mode="p")
            ).distinct()