chibisov / drf-extensions

DRF-extensions is a collection of custom extensions for Django REST Framework
http://chibisov.github.io/drf-extensions/docs
MIT License
1.47k stars 208 forks source link

Nested routes of a ManyToMany relation causes duplicate records to be returned. #170

Open harisibrahimkv opened 7 years ago

harisibrahimkv commented 7 years ago

Following 3 models:

class Institution(models.Model):
    name = models.CharField(max_length=300)

class StudentGroup(models.Model):
    institution = models.ForeignKey(Institution)
    name = models.CharField(max_length=50)
    students = models.ManyToManyField(
        'Student',
        related_name='studentgroups',
     )

class Student(models.Model):
    first_name = models.CharField(max_length=50, blank=True, null=True)

My nested routes are as follows:

nested_router = ExtendedSimpleRouter()
nested_router.register(
    r'institutions',
    InstitutionViewSet,
    base_name='institution'
).register(
    r'studentgroups',
    StudentGroupViewSet,
    base_name='studentgroup',
    parents_query_lookups=['institution']
).register(
    r'students',
    StudentViewSet,
    base_name='nested_students',
    parents_query_lookups=['studentgroups__institution', 'studentgroups']
)

When I hit /institutions/id/studentgroups/id/students/, it returns duplicate entries, which is an expected behavior as far as Django is concerned. However, that's not what the user expects as the response. To make it distinct, I had to do the following workaround on my StudentViewSet:

class StudentViewSet(NestedViewSetMixin, viewsets.ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer

    def filter_queryset_by_parents_lookups(self, queryset):
        parents_query_dict = self.get_parents_query_dict()
        if parents_query_dict:
            try:
                return queryset.filter(
                    **parents_query_dict
                ).order_by().distinct('id')
            except ValueError:
                raise Http404
        else:
            return queryset

Since the queries are being handles by the NestedViewSetMixin, I think it should have some way of specifying a .distinct()? Or is this better handled somewhere else?

auvipy commented 5 years ago

whats the current status of this?