django-rest-framework icon indicating copy to clipboard operation
django-rest-framework copied to clipboard

generics/mixins: Move GenericAPIView code to GenericModelMixin

Open cfra opened this issue 2 years ago • 2 comments

There are third party libraries, for example ADRF, which provide their own customized implementation of APIView.

It is useful to be able to create GenericAPIView variants based on these customized APIView variants.

However, as GenericAPIView inherits directly from Django Rest Framework's APIView, there is no clean way to achieve this without duplicating the code of GenericAPIView.

Resolve this by moving the code of GenericAPIView to a mixin called GenericModelMixin and creating GenericAPIView by mixing GenericModelMixin with Django Rest Framework's APIView.

This way, other libraries like ADRF can mix GenericModelMixin with their customized APIView variant and resuse the code of the GenericModelMixin without duplicating it.

Note: Before submitting this pull request, please review our contributing guidelines.

Description

Please describe your pull request. If it fixes a bug or resolves a feature request, be sure to link to that issue. When linking to an issue, please use refs #... in the description of the pull request.

cfra avatar Sep 05 '23 12:09 cfra

I am not sure if the test failure for Python 3.9 is due to my change or due to something completely different.

If there is anything that I should address, please let me know. :slightly_smiling_face:

cfra avatar Sep 06 '23 10:09 cfra

To provide a bit more context, please allow me to show the following example code:

from adrf.views import APIView
from adrf.viewsets import ViewSetMixin
from rest_framework import mixins


class GenericAPIView(mixins.GenericModelMixin, APIView):
    """
    Base class for all other generic views.
    """
    pass


class GenericViewSet(ViewSetMixin, GenericAPIView):
    """
    The GenericViewSet class does not provide any actions by default,
    but does include the base set of generic view behavior, such as
    the `get_object` and `get_queryset` methods.
    """
    pass


class ModelViewSet(mixins.CreateModelMixin,
                   mixins.RetrieveModelMixin,
                   mixins.UpdateModelMixin,
                   mixins.DestroyModelMixin,
                   mixins.ListModelMixin,
                   GenericViewSet):
    """
    A viewset that provides default `create()`, `retrieve()`, `update()`,
    `partial_update()`, `destroy()` and `list()` actions.
    """
    pass

With the proposed change we can create async-capable ModelViewSet instances while keeping code duplication to an absolute minimum.

Without this change, I don't see any way to achieve the same thing short of copying all the code that is currently part of the GenericAPIView implementation which doesn't seem like a good idea, as these are implementation details and should best be maintained as part of rest-framework, imho.

Therefore it seems just logical to me to move the code that provides the functionality of GenericAPIView into a mixin to make it reuseable, same as it is already done in CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin and ListModelMixin.

If there are any other proposals how the same can be achieved in a different way, I am happy to hear about it. :slightly_smiling_face:

cfra avatar Sep 11 '23 10:09 cfra

Thanks, no.

lovelydinosaur avatar Mar 21 '24 15:03 lovelydinosaur

Is there any alternative that you can suggest?

cfra avatar Mar 25 '24 14:03 cfra