Django drf如何避免UniqueValidator中的objects.all()

Django drf如何避免UniqueValidator中的objects.all(),django,python-3.x,django-models,django-rest-framework,Django,Python 3.x,Django Models,Django Rest Framework,我有一个表示用户的序列化器类 class UserSerializer(BaseSerializer): uid = serializers.IntegerField(required=True) class Meta: model = User fields = "all" def validate(self, data): super().validate(data) validate_user_da

我有一个表示用户的序列化器类

class UserSerializer(BaseSerializer):
    uid = serializers.IntegerField(required=True)

    class Meta:
        model = User
        fields = "all"

    def validate(self, data):
        super().validate(data)
        validate_user_data(data=self.initial_data, user=self.instance)
        return data
用户的uid应该是唯一的,因此当收到post请求时,我真正想要的是将uid字段更改为:

    uid = serializers.IntegerField(required=True, validators=[validators.UniqueValidator(queryset=User.objects.all())])
这可能会起作用,问题是,这会触发一个sql查询,选择所有用户。 这可能会对系统产生非常大的影响,因为可能会有成千上万个这样的系统。 我真正想要的是将查询更改为
User.objects.get(uid=uid)
,它不会从数据库中选择每个用户。 但是,因为我在uid的序列化程序定义中,所以不能使用uid=uid,因为uid刚刚被定义

(…)这可能会起作用,问题是,这将触发一个sql查询,该查询将选择所有用户

这是不正确的。Django将过滤queryset,但过滤本身发生在数据库端

这不会查询
User
表中的所有项目。查询集不会被计算。它充当“根查询集”,将根据它构造查询

我们可以查阅:

使用as
qs\U过滤器

因此,它将在数据库级别进行过滤,从而提高效率

(…)这可能会起作用,问题是,这将触发一个sql查询,该查询将选择所有用户

这是不正确的。Django将过滤queryset,但过滤本身发生在数据库端

这不会查询
User
表中的所有项目。查询集不会被计算。它充当“根查询集”,将根据它构造查询

我们可以查阅:

使用as
qs\U过滤器

因此,它将在数据库级别进行过滤,从而提高效率。

请注意,这不会在数据库中触发
.all()
。Django将安装queryset。此处提供的
queryset
充当“根queryset”,其他查询可以从中产生。请注意,这不会在数据库中触发
.all()
。Django将安装queryset。这里提供的
queryset
充当“根queryset”,其他查询可以从中产生。
class UniqueValidator(object):

    # ...

    def __call__(self, value):
        queryset = self.queryset
        queryset = self.filter_queryset(value, queryset)
        queryset = self.exclude_current_instance(queryset)
        if qs_exists(queryset):
            raise ValidationError(self.message, code='unique')
    def filter_queryset(self, value, queryset):
        """
        Filter the queryset to all instances matching the given attribute.
        """
        filter_kwargs = {'%s__%s' % (self.field_name, self.lookup): value}
        return qs_filter(queryset, **filter_kwargs)
def qs_filter(queryset, **kwargs):
    try:
        return queryset.filter(**kwargs)
    except (TypeError, ValueError, DataError):
        return queryset.none()
SELECT user.*
FROM user
WHERE uid = the_uid
  AND id <> item_that_is_updated