我在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.
为什么会这样?
答案 0 :(得分:0)
Serializer不在乎较低级别是否存在异常,它仅在乎序列化/反序列化。因此,当您在已存在的POST中传递username
时,IntegrityError
在模型层(在序列化器传递数据之后)而不是在序列化器上引发,因此不知道它。
Serializer仅检查反序列化是否正确进行,即您传递的所有数据均符合序列化器中字段的定义。如果有效,它将继续进行下一步。
此外,Serializer.is_valid
仅处理ValidationError
,并保留词典以引用错误。对于错误,它根据ValidationError
决定是否从错误中引发raise_exception
。
您应该查看序列化程序的create
方法(ModelSerializer
和子类)来处理数据库级异常,因为ModelSerializer
的所有对象创建逻辑都已进入该方法。 (另请参见update
的更新方法。)
DRF提供ModelSerializer
以确保从反序列化数据创建和更新模型对象,应将其视为基本序列化程序定义的扩展。