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】:您应该在序列化程序级别和模型级别添加约束,以防在序列化程序之外创建记录。
所以假设记录有id
和owner
字段,在模型的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,并且可以弃用。我也得到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 身份验证