【问题标题】:Serializer field validation with nested serializer in Django Rest Framework在 Django Rest Framework 中使用嵌套序列化器进行序列化器字段验证
【发布时间】:2016-12-10 13:49:25
【问题描述】:

我有一个模型Manager,它有一个指向User 的ForeignKey。 为了更新托运人,我发送了一个带有嵌套对象的 PATCH 方法,例如 {"user": {"first_name": "John", "last_name": "Doe", "email": "john@doe.com"}

class CompanyManagerMeSerializer(serializers.ModelSerializer):
    user = UserMeSerializer()
    company = CompanyFullSerializer()

    def update(self, instance, validated_data):
        user_data = validated_data.pop('user', {})
        user = instance.user
        for key, val in user_data.items():
            setattr(user, key, val)
        user.save()

        company_data = validated_data.pop('company', {})
        company = instance.company
        for key, val in company_data.items():
            setattr(company, key, val)
        company.save()

        for key, val in validated_data.items():
            setattr(instance, key, val)
        instance.save()

        return instance

    class Meta:
        model = CompanyManager
        fields = ("pk", "user", "company", "display_name")
        read_only_fields = ("display_name",)

这一切正常,直到我在 UserMeSerializeremail 字段上添加了一个验证器:

class UserMeSerializer(serializers.ModelSerializer):
    email = serializers.EmailField(
        validators=[UniqueValidator(
            queryset=User.objects.all(),
            message=_("This email address is already used.")
        )]
    )

    class Meta:
        model = User
        fields = (
            'pk', 'first_name', 'last_name', 'username', 'email', 'date_joined', 'last_login'
        )
        read_only_fields = ('pk', 'date_joined', 'last_login')

现在验证将失败,因为 UserMeSerializer 没有获得 instance 参数,所以唯一检查不知道它找到的电子邮件地址是我们正在检查的那个...see the source of UniqueValidator

所以我的问题是:我如何告诉UserMeSerializer 我正在处理companymanager.user 实例?我应该覆盖is_valid吗?

【问题讨论】:

    标签: python django validation django-rest-framework serialization


    【解决方案1】:

    我相信编写一个扩展 UniqueValidator 的自定义验证器会有所帮助。 您可以检查上下文并相应地设置self.instance。为此,您必须实现set_context() 方法。

    【讨论】:

      猜你喜欢
      • 2018-07-06
      • 2017-07-28
      • 1970-01-01
      • 2018-06-23
      • 2015-03-20
      • 1970-01-01
      • 2023-01-10
      • 2014-11-09
      • 1970-01-01
      相关资源
      最近更新 更多