Django REST 验证器。多个用户可以拥有相同值的记录,但该记录对于每个用户都是唯一的,如何做到这一点?

Posted

技术标签:

【中文标题】Django REST 验证器。多个用户可以拥有相同值的记录,但该记录对于每个用户都是唯一的,如何做到这一点?【英文标题】:Django REST validator. Multiple users can have records with same value, but that record is unique for each user, how to do that? 【发布时间】:2020-09-12 09:12:14 【问题描述】:

我正在尝试使用 Django REST 框架完成以下任务。 我有模型记录,它有字段。它具有用户的外键。每个用户可以创建多个不同编号的记录,但不能为自己创建多个相同编号的记录。但是,每个其他用户都可以为自己创建具有相同编号的记录。 例如。用户乔和吉尔。 Joe 只能创建一次编号为 123 的记录,如果他尝试使用 123 再创建一个记录,则不应允许他。然而,吉尔可以为自己创造一次 123,但不能再创造更多。

我的猜测是在序列化器中创建一个验证器,也就是

class RecordSerializer(serializers.HyperlinkedModelSerializer):
    '''Serializer for Record'''

    class Meta:
        model = Record
        fields = [
            'user', 
            'number', 
            'otherfield', 
        ]

        validators = [
            UniqueValidator(
                queryset= Record.objects.filter(user=<current user>),
            )
        ]

但是,我无法在验证器属性中获取当前用户,否则我该如何完成此操作?

【问题讨论】:

【参考方案1】:

您应该在序列化程序级别和模型级别添加约束,以防在序列化程序之外创建记录。 所以假设记录有idowner 字段,在模型的Meta 类中添加unique_together 属性:

class Meta:
    unique_together = (('id', 'owner'))

然后在序列化器中,可以使用CurrentUserDefault高级字段来捕获登录用户。

from rest_framework.validators import UniqueTogetherValidator


class RecordSerializer(serializer.ModelSerializer):
    owner = serializers.HiddenField(
        default=serializers.CurrentUserDefault()
    )

    class Meta:
        validators = [
            UniqueTogetherValidator(
                queryset=Record.objects.all(),
                fields=['id', 'owner']
            )
        ]

当然,序列化器应该用在需要认证的视图中

【讨论】:

伙计们! @Andee 和 @Ken4Sholars!非常感谢!我花了一整天的时间寻找解决方案! ***.com/a/55786819/7027427 的这个答案指出 UniqueConstraints 应该优于 unique_together,并且可以弃用。我也得到 迁移时指向这些字段的错误。 是的,这只是在新版本的 Django 中指定唯一约束的首选方式,所以如果你有这样的版本,请继续使用它而不是 unique_together。至于IntegrityError,您似乎违反了唯一约束。这正是它通知开发人员它被违反的方式。我怀疑您是在序列化程序之外创建记录。表示该用户已经拥有该号码的记录。此外,您可能希望将我的回答中的 id 字段重命名为您在问题中描述的数字字段 我在数据库中有违反约束的记录。删除它们并修复:) 再次非常感谢。【参考方案2】:

在您的模型 Meta 上,设置 unique_together https://docs.djangoproject.com/en/3.0/ref/models/options/#unique-together

【讨论】:

以上是关于Django REST 验证器。多个用户可以拥有相同值的记录,但该记录对于每个用户都是唯一的,如何做到这一点?的主要内容,如果未能解决你的问题,请参考以下文章

如何使 Django REST JWT 身份验证与多个 Web 服务器一起扩展?

Django REST 的 JSON Web 令牌不会向用户数据库进行身份验证

如何查看数据库中是不是有其他用户具有相同的用户名 - JWT Django REST 身份验证

django rest框架中多个视图的相同验证

从 Django Rest Framework 将经过身份验证的用户传递给 SendBird

Angular 2 前端 django 2 REST 框架后端用户身份验证