从下面的代码中,您可以看到我使用了modelviewset
,自定义list
方法和名为get_recent_movies
的自定义操作。
class MoviesViewSet(LoginRequiredMixin, ModelViewSet):
authentication_classes = (authentication.SessionAuthentication,)
permission_classes = (permissions.IsAuthenticated,)
queryset = Movie.objects.all()
serializer_class = MovieSerializer
filter_backends = (django_filters.rest_framework.DjangoFilterBackend,
rest_framework.filters.SearchFilter,
rest_framework.filters.OrderingFilter)
filter_class = MovieFilter
search_fields = {"title", "genre", "country", "language"}
ordering_fields = ("title", "genre", "country", "language", "release_year", "timestamp")
def get_queryset(self):
queryset = Movie.objects.filter(user=self.request.user).select_related()
return queryset
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
# Check for Datatables and server side processing parameters
draw = self.request.query_params.get("draw", None)
start = self.request.query_params.get("start", None)
length = self.request.query_params.get("length", None)
if draw and start and length:
draw = int(draw)
start = int(start)
length = int(length)
queryset = queryset[start:start+length]
serializer = MovieListSerializer(queryset, many=True)
result = {"draw": draw,
"recordsTotal": total_count,
"recordsFiltered": total_count,
"data": serializer.data}
return Response(result)
else:
serializer = MovieListSerializer(queryset, many=True)
return Response(serializer.data)
@action(methods=["get"], detail=False,
url_path="recent", url_name="recent")
def get_recent_movies(self, request):
queryset = self.filter_queryset(self.get_queryset())
queryset = queryset.filter(status=1).order_by("-timestamp")[:12]
serializer = MovieListSerializer(queryset, many=True)
return Response(serializer.data)
使用自定义list
方法的原因是我使用Datatables和服务器端处理,因此必须以正确的方式格式化数据。
我使用get_recent_movies
获取用户最近看过的12部电影。
问题在于,get_recent_movies
中的数据在显示在表中时需要格式化。我可以在自定义操作中重复使用list方法,但我不想这样做。
我不确定如何将查询集从自定义操作传递到列表方法。
答案 0 :(得分:0)
尝试一下
class MoviesViewSet(LoginRequiredMixin, ModelViewSet):
# your code
def get_queryset(self):
queryset = Movie.objects.filter(user=self.request.user).select_related()
return queryset
def check_data_tables(self, queryset):
# Check for Datatables and server side processing parameters
draw = self.request.query_params.get("draw", None)
start = self.request.query_params.get("start", None)
length = self.request.query_params.get("length", None)
if draw and start and length:
draw = int(draw)
start = int(start)
length = int(length)
queryset = queryset[start:start + length]
serializer = MovieListSerializer(queryset, many=True)
return {"draw": draw,
"recordsTotal": total_count,
"recordsFiltered": total_count,
"data": serializer.data}
return {}
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
result = self.check_data_tables(queryset)
if result:
return Response(result)
else:
serializer = MovieListSerializer(queryset, many=True)
return Response(serializer.data)
@action(methods=["get"], detail=False, url_path="recent", url_name="recent")
def get_recent_movies(self, request):
queryset = self.filter_queryset(self.get_queryset())
queryset = queryset.filter(status=1).order_by("-timestamp")[:12]
serializer = MovieListSerializer(queryset, many=True)
"""
if some condtion:
call check_data_tables() method
"""
if condition:
result = result = self.check_data_tables(queryset)
return processed response
return Response(serializer.data)
我在这里做了什么?
我创建了 check_data_tables()
的类方法,该方法对于两个操作 list
和 get_recent_movies
使用 self
答案 1 :(得分:0)
这是您实现目标的另一种方法:
class MoviesViewSet(LoginRequiredMixin, ModelViewSet):
authentication_classes = (authentication.SessionAuthentication,)
permission_classes = (permissions.IsAuthenticated,)
queryset = Movie.objects.all()
serializer_class = MovieSerializer
filter_backends = (django_filters.rest_framework.DjangoFilterBackend,
rest_framework.filters.SearchFilter,
rest_framework.filters.OrderingFilter)
filter_class = MovieFilter
search_fields = {"title", "genre", "country", "language"}
ordering_fields = ("title", "genre", "country", "language", "release_year", "timestamp")
def get_queryset(self):
queryset = Movie.objects.filter(user=self.request.user).select_related()
if self.action == 'get_recent_movies':
queryset = queryset.filter(status=1).order_by("-timestamp")[:12]
return queryset
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
# Check for Datatables and server side processing parameters
draw = self.request.query_params.get("draw", None)
start = self.request.query_params.get("start", None)
length = self.request.query_params.get("length", None)
if draw and start and length:
draw = int(draw)
start = int(start)
length = int(length)
queryset = queryset[start:start+length]
serializer = MovieListSerializer(queryset, many=True)
result = {"draw": draw,
"recordsTotal": total_count,
"recordsFiltered": total_count,
"data": serializer.data}
return Response(result)
else:
serializer = MovieListSerializer(queryset, many=True)
return Response(serializer.data)
@action(methods=["get"], detail=False, url_path="recent", url_name="recent")
def get_recent_movies(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
请注意get_queryset
方法。在这里您可以控制要向自定义操作提供哪些数据。