我已经使用了基于对象的自定义查询集的API视图。我通过url中提供的pk
获取对象。
我想返回带有分页对象的所有相关实例。
class ListVotedAPIView(generics.ListAPIView, VoteModelMixin):
serializer_class = UserSerializer
def get(self, request, *args, **kwargs):
return self.voted(request)
def get_queryset(self):
instance = self.get_object()
return services.get_voted(instance)
class VoteModelMixin:
def voted(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
这是services.get_voted()
:
def get_voted(obj):
"""
Return all users that voted `obj`.
"""
obj_type = ContentType.objects.get_for_model(obj)
return User.objects.filter(
votes__content_type=obj_type,
votes__object_id=obj.id
)
问题在于get_object()
是根据get_queryset()
我收到以下错误:RecursionError: maximum recursion depth exceeded
如何覆盖get_object()
方法,该方法将可用于不同的模型?
已更新
class CommentLikeAPIView(generics.CreateAPIView, ):
queryset = Comment.objects.all()
serializer_class = LikeSerializer
@staticmethod
def get_contenttype():
return ContentType.objects.get(model='comment')
def get_serializer_context(self):
"""
Extra context provided to the serializer class.
"""
return {'request': self.request,
'format': self.format_kwarg,
'view': self,
'content_type': self.get_contenttype(),
'pk': self.kwargs.get('pk')}
答案 0 :(得分:1)
问题是您根据get_queryset
定义了get_object
,但是get_object
被定义为:
def get_object(self): # ... queryset = self.filter_queryset(self.get_queryset()) # Perform the lookup filtering. lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field assert lookup_url_kwarg in self.kwargs, ( 'Expected view %s to be called with a URL keyword argument ' 'named "%s". Fix your URL conf, or set the `.lookup_field` ' 'attribute on the view correctly.' % (self.__class__.__name__, lookup_url_kwarg) ) filter_kwargs = {self.lookup_field: self.kwargs[lookup_url_kwarg]} obj = get_object_or_404(queryset, **filter_kwargs) # May raise a permission denied self.check_object_permissions(self.request, obj) return obj
因此,这意味着.get_queryset(..)
将调用.get_object(..)
,然后再次调用.get_queryset(..)
,此过程将继续进行,直到最终导致调用堆栈溢出。
因此,您将需要以某种方式破坏此相互递归,例如,通过实现一个不不依赖于get_queryset
的{{1}},或者通过覆盖不依赖于get_object
的{{1}}的{{1}}。
例如:
get_object
(假设您只会提供get_queryset
,那么也许您需要实现更复杂的功能)。
注意:您可能还希望在
def get_object(self): # ... queryset = self.filter_queryset(this.model.objects.all()) # ... return get_object_or_404(queryset, **filter_kwargs)
中传递Model
和*args
,例如:**kwargs