Python django rest框架中的更改列表视图输出字段

Python django rest框架中的更改列表视图输出字段,python,django,api,django-rest-framework,Python,Django,Api,Django Rest Framework,我是Django和Django Rest框架的新手,在解决这个问题时遇到了一些问题 我有一个训练的模型,它包含一个标题和一个多对多关系字段练习。 在为模型创建api时,我继承了viewset.ModelViewSet类-根据我的理解,该类设置了rest api的常见用途(列表、创建、更新等) 这很好,但是,当访问/api/workouts/时,我会得到所有训练的列表,包括分配给训练的所有训练,我觉得输入所有训练数据有点浪费,用户可能永远看不到 我更喜欢使用/api/workouts/不返回练习,

我是Django和Django Rest框架的新手,在解决这个问题时遇到了一些问题

我有一个
训练的模型
,它包含一个标题和一个多对多关系字段
练习
。 在为模型创建api时,我继承了
viewset.ModelViewSet
类-根据我的理解,该类设置了rest api的常见用途(列表、创建、更新等)

这很好,但是,当访问
/api/workouts/
时,我会得到所有训练的列表,包括分配给训练的所有训练,我觉得输入所有训练数据有点浪费,用户可能永远看不到

我更喜欢使用
/api/workouts/
不返回
练习
,并且只有当用户使用
/api/workouts/1
访问训练时,才会显示练习

我的序列化程序类

class WorkoutSerializer(serializers.ModelSerializer):
    exercises = ExerciseSerializer(read_only=True, many=True)

    class Meta:
        model = Workout
        fields = ('id', 'title', 'exercises')
在我看来,

class WorkoutView(viewsets.ModelViewSet):
    queryset = Workout.objects.all()
    serializer_class = WorkoutSerializer

    def list(self, request):
        workouts_list = self.get_queryset().defer('exercises');
        serializer = self.get_serializer(workouts_list, many=True)
        return response.Response(serializer.data)
我最近的尝试是覆盖list方法并用queryset删除字段,但似乎我删除字段的任何操作都没有影响

TL;DR I希望继续使用
ModelViewSet
,但从主列表视图
/api/workouts/
中删除字段
练习
,并将其保留在详细视图
/api/workouts/1/


提前感谢您的建议。

您可以通过从
ModelViewSet
的所有父类(除了
ListModelMixin
之外)创建自己的自定义类,而不是从
ModelViewSet
继承

from rest_framework import mixins

class MyCustomModelViewSet(
        mixins.CreateModelMixin,
        mixins.RetrieveModelMixin,
        mixins.UpdateModelMixin,
        mixins.DestroyModelMixin,
        mixins.ListModelMixin,
        GenericViewSet,
    ):
        pass
从rest\u框架导入混合
类MyCustomModelViewSet(
mixin.CreateModelMixin,
mixin.RetrieveModelMixin,
mixin.UpdateModelMixin,
mixin.DestroyModelMixin,
mixin.ListModelMixin,
GenericViewSet,
):
通过
总是会给你一个关于你的锻炼的查询集,就像把它叫做

@property
def excercises(self):
   return self.excercises.all()
   and then its always going to give you a queryset with all fields
我假设您的模型有一个string方法,您所需要的只是至少一个exercise或id的名称。如果是这样,那么:

exercises = serializers.StringRelatedField(many=True)

将帮助您

一个可能的解决方案是为详细视图和列表视图创建单独的视图集和序列化程序

在api/viewsets.py中

Class WorkoutListView(viewsets.ModelViewSet):
    queryset = Workout.objects.all()
    serializer_class = WorkoutListSerializer


Class WorkoutDetailView(viewsets.ModelViewSet):
    queryset = Workout.objects.all()
    serializer_class = WorkoutDetailSerializer
在api/serializers.py中

class WorkoutListSerializer(serializers.ModelSerializer):

class Meta:
    model = Workout
    fields = ('id', 'title')


class WorkoutDetailSerializer(serializers.ModelSerializer):
    exercises = ExerciseSerializer(read_only=True, many=True)

class Meta:
    model = Workout
    fields = ('id', 'title', 'exercises')
在api/URL.py中,这是重要的部分。对列表视图执行常规的router.register()

router.register(r'workouts', viewsets.WorkoutListView)
但是您需要为带有pk的详细视图定义一个路径

from django.urls import path
urlpatterns = [
    path('workouts/<pk>/', viewsets.WorkoutDetailView.as_view({'get': 'retrieve'}))
]
从django.url导入路径
URL模式=[
路径('workouts/',viewset.WorkoutDetailView.as_视图({'get':'retrieve'}))
]
在这一点上,只需确保将url_模式包括到api中,就可以开始了

from django.urls import path
urlpatterns = [
    path('workouts/<pk>/', viewsets.WorkoutDetailView.as_view({'get': 'retrieve'}))
]