简体   繁体   English

带有源字段的UniqueValidator

[英]UniqueValidator with source field

I have model UserProfile: 我有模型UserProfile:

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

and serializer: 和序列化器:

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

Serialization works fine, but deserialization doesn't — it tries to file 'user.email' field in User model, and, of course, fails. 序列化工作正常,但是反序列化却不能—尝试在用户模型中归档“ user.email”字段,当然会失败。

If I change User to UserProfile in the queryset, it fails with another error: 如果我在查询集中将用户更改为UserProfile,它将失败并出现另一个错误:

invalid literal for int() with base 10: 'admin@localhost' 以10为底的int()的无效文字:“ admin @ localhost”

Is it possible to set different sources for serialization and deserialization? 可以为序列化和反序列化设置不同的来源吗?

By default, the UniqueValidator expects that the source (or field name, if no source is given) can be used in the queryset that is provided to filter out the existing object . 默认情况下, UniqueValidator预计, source (或字段名称,如果没有source给出)可以在所使用的queryset被提供给过滤掉现有的对象 So by using a source that spans a relation (and has a dot), it will try to use that name when filtering the queryset which fails, as you've noticed. 因此,正如您所注意到的,通过使用跨越关系(并带有点)的源,它将在过滤失败的查询集时尝试使用该名称。

You can fix this by subclassing UniqueValidator to override the filter_queryset method to filter it differently. 您可以通过子类化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)

This hard codes email as the filter, one possible option for not hard coding it would be to split self.field_name and get the last part of the dotted source. 将此email硬编码为过滤器,不进行硬编码的一种可能选择是拆分self.field_name并获得点缀源的最后一部分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM