具有源字段的UniqueValidator

时间:2015-08-03 18:16:52

标签: django django-rest-framework

我的模型是UserProfile:

class UserProfile(models.Model):
   user = models.OneToOneField(User)

和序列化器:

email = serializers.CharField(source='user.email', required=False,
                                  validators=[UniqueValidator(queryset=User.objects.all())])

序列化工作正常,但反序列化没有 - 它试图提交' user.email'用户模型中的字段,当然,失败。

如果我在查询集中将User更改为UserProfile,则会失败,并显示另一个错误:

  

基数为10的int()的文字无效:' admin @ localhost'

是否可以为序列化和反序列化设置不同的来源?

1 个答案:

答案 0 :(得分:2)

默认情况下,UniqueValidator期望source(或字段名称,如果没有source)可以在queryset中提供给{ {3}}。因此,通过使用跨越关系的源(并且具有点),当过滤掉失败的查询集时,它会尝试使用该名称,如您所知。

您可以通过继承UniqueValidator来覆盖filter_queryset方法以不同方式对其进行过滤来解决此问题。

class CustomUniqueValidator(UniqueValidator):

    def filter_queryset(self, value, queryset):
        """
        Filter the queryset to all instances matching the given attribute.
        """
        filter_kwargs = {"email": value}
        return queryset.filter(**filter_kwargs)

这个硬编码email作为过滤器,一个不用硬编码的可能选项就是拆分self.field_name并获取虚线源的最后一部分。