python - DRF 验证器在唯一性检查时不返回 false
问题描述
我在 DRF 中有一个用户序列化程序,如下所示:
class UserSerializer(serializers.ModelSerializer):
class Meta: # password should exist only if POST
model = User
fields = ['first_name', 'last_name',
'password', 'email', 'username']
write_only_fields = ['password']
这就是我检查外壳时的样子。
UserSerializer():
first_name = CharField(allow_blank=True, max_length=30, required=False)
last_name = CharField(allow_blank=True, max_length=150, required=False)
password = CharField(max_length=128)
email = EmailField(allow_blank=True, label='Email address', max_length=254, required=False)
username = CharField(help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, validators=[<django.contrib.auth.validators.UnicodeUsernameValidator object>, <UniqueValidator(queryset=User.objects.all())>])
在我看来,如果我is_valid()
使用数据库中已经存在的数据检查序列化程序,该函数在应该返回 False 时返回 True,然后引发 django 错误:
django.db.utils.IntegrityError: duplicate key value violates unique constraint "auth_user_username_key"
DETAIL: Key (username)=(myrandomusername) already exists.
为什么会这样?
解决方案
序列化器不关心底层是否有异常,只关心序列化/反序列化。username
因此,当您在已经存在的 POST 中传递 a时,IntegrityError
会在模型层(在序列化程序传递数据之后)而不是在序列化程序上引发,因此它不知道。
序列化程序仅检查反序列化是否正确进行,即您传递的所有数据都符合序列化程序中字段的定义。如果它们是有效的,它将传递到下一步。
此外,Serializer.is_valid
仅处理ValidationError
,并保留字典以引用错误。对于错误,它决定是否引发ValidationError
(从错误中)基于raise_exception
.
您应该查看create
序列化程序(ModelSerializer
和子类)的方法来处理数据库级异常,因为所有对象创建逻辑ModelSerializer
都在其中。(另请查看update
更新方法)。
DRF 提供ModelSerializer
了确保从反序列化数据创建和更新模型对象的功能,它应该被视为对基本序列化程序定义的扩展。
推荐阅读
- javascript - 如何通过不在引号中的正则表达式拆分文本
- python - 如何在python中编辑矩阵中的值?
- ascii - 为什么 '[' 和 ']' ASCII 码不相互跟随?
- python - OSError: [WinError 126] 未找到模块
- javascript - Github 网页外部 css 无法正常工作,但 js 工作正常
- docker - Nuxt.js SSR w/ Nest API 在 Docker 容器中部署到 AWS
- android - 如何在flutter中使用fxpoi包读取CSV文件
- python - 使用 keras 将图像划分为子部分
- python - Python同时监听和分析数据
- python-3.x - Pandas 对条形图进行分组和重采样: