8

在我的User个人资料模型中,我show_email明确包含了一个字段。因此,要将此功能添加到我的 API,UserSerializer 类如下所示:

class UserSerializer(serializers.ModelSerializer):
    email = serializers.SerializerMethodField('show_email')

    def show_email(self, user):
        return user.email if user.show_email else None

    class Meta:
        model = django.contrib.auth.get_user_model()
        fields = ("username", "first_name", "last_name", "email")

但我真的不喜欢它。我认为如果该字段email完全从序列化程序输出中排除show_emailFalse而不是显示那个丑陋"email": null的东西,那会更干净。

我怎么能那样做?

4

4 回答 4

3

您可以通过覆盖返回响应的方法(即 API 视图的“动词”)在您的 API 视图中执行此操作。例如,在 ListAPIView 中,您将覆盖get()

class UserList(generics.ListAPIView):
    model = django.contrib.auth.get_user_model()
    serializer_class = UserSerializer

    def get(self, request, *args, **kwargs):
        response = super(UserList, self).get(request, *args, **kwargs)
        for result in response.data['results']:
            if result['email'] is None:
                result.pop('email')
        return response

您可能希望添加更多属性检查,但这就是如何完成的要点。另外,我还要补充一点,如果从某些结果中删除字段可能会导致消费应用程序出现问题,如果它希望它们出现在所有记录中。

于 2013-09-15T15:35:01.143 回答
3

这个答案来晚了,但对于未来的谷歌搜索:文档中有一个关于Dynamically modifying fields的示例。因此,通过将参数传递给序列化程序,您可以控制是否处理字段:

serializer = MyPostSerializer(posts, show_email=permissions)

然后在序列化程序的init函数中,您可以执行以下操作:

class MyPostSerializer(serializers.ModelSerializer):

def __init__(self, *args, **kwargs):
    show_email = kwargs.pop('show_email', None)

    # Instantiate the superclass normally
    super(DeviceSerializer, self).__init__(*args, **kwargs)

    if not show_email:
        self.fields.pop("show_email")

现在show_email字段将被序列化程序忽略。

于 2014-11-14T05:05:13.793 回答
0

您可以覆盖序列化程序上的 restore_fields 方法。在 restore_fields 方法中,您可以修改字段列表 - serializer.fields - 弹出、推送或修改任何字段。

例如:当操作不是“创建”时,字段工作区是只读的

class MyPostSerializer(ModelSerializer):

def restore_fields(self, data, files):
    if (self.context.get('view').action != 'create'):
        self.fields.get('workspace').read_only=True
    return super(MyPostSerializer, self).restore_fields(data, files)

class Meta:
    model = MyPost
    fields = ('id', 'name', 'workspace')
于 2014-01-22T08:31:42.593 回答
0

这可能会有所帮助...要在 API 请求中动态包含或排除字段,应修改下面的 @stackedUser 响应:

  class AirtimePurchaseSerializer(serializers.Serializer):

      def __init__(self, *args, **kwargs):
        try:
            phone = kwargs['data']['res_phone_number']
        except KeyError:
            phone = None

        # Instantiate the superclass normally
        super(AirtimePurchaseSerializer, self).__init__(*args, **kwargs)

        if not phone:
            self.fields.pop("res_phone_number")

     res_phone_number = serializers.CharField(max_length=16, allow_null=False)
于 2021-09-14T17:04:20.667 回答