Django rest框架是否在列表显示中隐藏特定字段?

2024-05-16 08:35:04 发布

您现在位置:Python中文网/ 问答频道 /正文

I want to hide specific fields of a model on the list display at persons/ and show all the fields on the detail display persons/jane

我对rest框架还比较陌生,文档感觉很难掌握。

这就是我想要完成的。

我有一个简单的模型

# model
class Person(models.Model):
    first_name = models.CharField(max_length=30, blank=True)
    last_name = models.CharField(max_length=30, blank=True)
    nickname = models.CharField(max_length=20)
    slug = models.SlugField()
    address = models.TextField(max_length=300, blank=True)

以及序列化程序类

# serializers

class PersonListSerializer(serializers.ModelSerializer):
    class Meta:
        model = Person
        fields = ('nickname', 'slug')


class PersonSerializer(serializers.ModelSerializer):
    class Meta:
        model = Person
        fields = ('first_name', 'last_name', 'nickname', 'slug', 'address')

以及视图集。

# view sets (api.py)

class PersonListViewSet(viewsets.ModelViewSet):
    queryset = Person.objects.all()
    serializer_class = PersonListSerializer


class PersonViewSet(viewsets.ModelViewSet):
    queryset = Person.objects.all()
    serializer_class = PersonSerializer

在urlpersons处,我想显示人员列表,只显示字段nicknameslug,在urlpersons/[slug]处,我想显示模型的所有字段。

我的路由器配置

router = routers.DefaultRouter()
router.register(r'persons', api.PersonListViewSet)
router.register(r'persons/{slug}', api.PersonViewSet)

我想第二种配置是错误的,我怎样才能达到我想要做的呢?

更新:

persons/slug的输出是{"detail":"Not found."},但它适用于person/pk

谢谢你


Tags: thenamefieldsmodelmodelsnicknamealllength
3条回答

如果要更改“列表与详细信息”视图中显示的字段,则只能更改使用的序列化程序。我知道没有哪个字段可以让您指定使用序列化程序的哪些字段。

您可以重写序列化程序类的'get_fields'方法并添加类似的内容:

def get_fields(self, *args, **kwargs):
    fields = super().get_fields(*args, **kwargs)
    request = self.context.get('request')
    if request is not None and not request.parser_context.get('kwargs'):
        fields.pop('your_field', None)
    return fields

在这种情况下,当您得到详细视图时,会有“kwargs”:{'pk':404}并且当您得到列表视图时,会有“kwargs”:{}

对于其他遇到此问题的人,我发现重写视图集上的get_serializer_类并为每个操作定义序列化程序是最简单的选择(保留单个视图集,但允许动态序列化程序选择):

class MyViewset(viewsets.ModelViewSet):
    serializer_class = serializers.ListSerializer
    permission_classes = [permissions.IsAdminUser]
    renderer_classes = (renderers.AdminRenderer,)
    queryset = models.MyModel.objects.all().order_by('-updated')

    def __init__(self, *args, **kwargs):
        super(MyViewset, self).__init__(*args, **kwargs)
        self.serializer_action_classes = {
            'list':serializers.AdminListSerializer,
            'create':serializers.AdminCreateSerializer,
            'retrieve':serializers.AdminRetrieveSerializer,
            'update':serializers.AdminUpdateSerializer,
            'partial_update':serializers.AdminUpdateSerializer,
            'destroy':serializers.AdminRetrieveSerializer,
        }

    def get_serializer_class(self, *args, **kwargs):
        """Instantiate the list of serializers per action from class attribute (must be defined)."""
        kwargs['partial'] = True
        try:
            return self.serializer_action_classes[self.action]
        except (KeyError, AttributeError):
            return super(MyViewset, self).get_serializer_class()

希望这能帮助别人。

相关问题 更多 >