77from django .utils .translation import gettext_lazy as _
88from rest_framework .exceptions import ValidationError
99from rest_framework .generics import get_object_or_404
10+ from rest_framework .mixins import RetrieveModelMixin , ListModelMixin
1011from rest_framework .response import Response
1112from rest_framework .serializers import ListSerializer
1213
@@ -152,8 +153,17 @@ def get_sideloading_serializer_context(self):
152153 # modified DRF methods
153154
154155 def retrieve (self , request , * args , ** kwargs ):
156+ if not isinstance (self , RetrieveModelMixin ):
157+ # The viewset does not have RetrieveModelMixin and therefore the method is not allowed
158+ return self .http_method_not_allowed (request , * args , ** kwargs )
159+
155160 if self .sideloading_query_param_name not in request .query_params :
156- return super ().retrieve (request , * args , ** kwargs )
161+ try :
162+ return super ().retrieve (request = request , * args , ** kwargs )
163+ except AttributeError :
164+ # self.retrieve() method was not declared before this mixin.
165+ # Make sure the SideloadableRelationsMixin is defined higher than RetrieveModelMixin.
166+ return self .http_method_not_allowed (request , * args , ** kwargs )
157167
158168 (
159169 sideloading_serializer_class ,
@@ -166,7 +176,12 @@ def retrieve(self, request, *args, **kwargs):
166176 ) = self .get_sideloading_variables_from_serializer (request = request )
167177
168178 if not relations_to_sideload :
169- return super ().retrieve (request , * args , ** kwargs )
179+ try :
180+ return super ().retrieve (request = request , * args , ** kwargs )
181+ except AttributeError :
182+ # self.retrieve() method was not declared before this mixin.
183+ # Make sure the SideloadableRelationsMixin is defined higher than RetrieveModelMixin.
184+ return self .http_method_not_allowed (request , * args , ** kwargs )
170185
171186 # return object with sideloading serializer
172187 queryset , relations_sources = self .get_sideloadable_object_as_queryset (
@@ -189,8 +204,17 @@ def retrieve(self, request, *args, **kwargs):
189204 return Response (serializer .data )
190205
191206 def list (self , request , * args , ** kwargs ):
207+ if not isinstance (self , ListModelMixin ):
208+ # The viewset does not have ListModelMixin and therefore the method is not allowed
209+ return self .http_method_not_allowed (request , * args , ** kwargs )
210+
192211 if request .method != "GET" or self .sideloading_query_param_name not in request .query_params :
193- return super ().list (request , * args , ** kwargs )
212+ try :
213+ return super ().list (request = request , * args , ** kwargs )
214+ except AttributeError :
215+ # self.list() method was not declared before this mixin.
216+ # Make sure the SideloadableRelationsMixin is defined higher than ListModelMixin.
217+ return self .http_method_not_allowed (request , * args , ** kwargs )
194218
195219 (
196220 sideloading_serializer_class ,
@@ -203,7 +227,12 @@ def list(self, request, *args, **kwargs):
203227 ) = self .get_sideloading_variables_from_serializer (request = request )
204228
205229 if not relations_to_sideload :
206- return super ().list (request , * args , ** kwargs )
230+ try :
231+ return super ().list (request = request , * args , ** kwargs )
232+ except AttributeError :
233+ # self.list() method was not declared before this mixin.
234+ # Make sure the SideloadableRelationsMixin is defined higher than ListModelMixin.
235+ return self .http_method_not_allowed (request , * args , ** kwargs )
207236
208237 # After this `relations_to_sideload` is safe to use
209238 queryset = self .get_queryset ()
0 commit comments