django rest serializer中的read_only字段,带有unique_together约束

时间:2015-08-10 06:28:38

标签: python django serialization django-rest-framework

我想在默认的django用户模型中使电子邮件字段唯一。所以我做到了unique_together=[('email',)]。现在在序列化器中我希望它是一个read_only字段。 但是Django Rest Framework 3.0文档说:

  

有一种特殊情况,只读字段是a的一部分   在模型级别的unique_together约束。在这种情况下的领域   序列化程序类需要验证   约束,但也不应该被用户编辑。

     

处理此问题的正确方法是明确指定字段   序列化程序,提供read_only = True和default = ...   关键字参数。

     
    

这方面的一个例子是对当前的只读关系     经过身份验证的用户,与另一个标识符唯一。     在这种情况下,您将声明用户字段,如下所示:

  
     

user = serializers.PrimaryKeyRelatedField(read_only = True,   默认= serializers.CurrentUserDefault())

serializers.CurrentUserDefault()表示当前用户。我想将默认值设置为用户的电子邮件。 serializers.CurrentUserDefault()不等同于request.userserializers.CurrentUserDefault().email提供错误'CurrentUserDefault' object has no attribute 'email'如何将电子邮件默认设置为用户的电子邮件?

2 个答案:

答案 0 :(得分:2)

这是CurrentUserDefault的文档所说的内容:

  

可用于表示当前用户的默认类。在   为了使用这个,请求'必须是作为一部分提供的   实例化序列化程序时的上下文字典。

您可以这样做,也可以提供context data views中传递的电子邮件ID。覆盖函数get_serializer_context

def get_serializer_context(self):
    context = super(YourClass, self).get_serializer_context()
    context['email'] = request.user.email

    return context

views中。您的view应该在某个继承级别从GenericAPIView扩展。现在在serializer中,覆盖您的__init__并获取您的电子邮件数据。

def __init__(self, instance = None,  data = serializers.empty, *args, **kwargs):
    self.email = kwargs['context']['email']

现在您可以在序列化程序中使用它。

答案 1 :(得分:0)

请检查this answer中的解决方案2

代码可以是:

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('id', 'email',)
        extra_kwargs = {
            'email': {'read_only': True},
        }


    def create(self, validated_data):
        """Override create to provide a email via request.user by default."""
        if 'email' not in validated_data:
            validated_data['email'] = self.context['request'].user.email

        return super(UserSerializer, self).create(validated_data)

希望有帮助:)