Python Django Rest框架编号类型仍然通过模型验证
您好,我目前正在尝试为我的更新API编写验证。我在序列化程序中使用了类似的模型字段,因为我只希望在自定义用户模型中更新这些字段:Python Django Rest框架编号类型仍然通过模型验证,python,django,validation,django-rest-framework,Python,Django,Validation,Django Rest Framework,您好,我目前正在尝试为我的更新API编写验证。我在序列化程序中使用了类似的模型字段,因为我只希望在自定义用户模型中更新这些字段: class UpdateUserSerializer(serializers.ModelSerializer): class Meta: model = User fields = ( 'email', 'uid', 'nickname', 'eth_address', 'eth_private_key', 'evt_ad
class UpdateUserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = (
'email', 'uid', 'nickname', 'eth_address', 'eth_private_key', 'evt_address', 'evt_private_key'
)
Class User(AbstractUser):
uid = models.CharField(
"uid", max_length=255, null=True, blank=True)
phone_number = models.CharField(
"Phone number", max_length=255, null=True, blank=True)
nickname = models.CharField(
"Nickname", max_length=255, null=True, blank=True)
status = models.PositiveSmallIntegerField("Status", default=0)
eth_address = models.CharField(
"Eth address", max_length=255, null=True, blank=True)
eth_private_key = models.CharField(
"Eth private key", max_length=255, null=True, blank=True)
evt_address = models.CharField(
"Evt address", max_length=255, null=True, blank=True)
evt_private_key = models.CharField(
"Evt private key", max_length=255, null=True, blank=True)
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
# deleted
class Meta:
db_table = "users"
pass
我的用户模型:
class UpdateUserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = (
'email', 'uid', 'nickname', 'eth_address', 'eth_private_key', 'evt_address', 'evt_private_key'
)
Class User(AbstractUser):
uid = models.CharField(
"uid", max_length=255, null=True, blank=True)
phone_number = models.CharField(
"Phone number", max_length=255, null=True, blank=True)
nickname = models.CharField(
"Nickname", max_length=255, null=True, blank=True)
status = models.PositiveSmallIntegerField("Status", default=0)
eth_address = models.CharField(
"Eth address", max_length=255, null=True, blank=True)
eth_private_key = models.CharField(
"Eth private key", max_length=255, null=True, blank=True)
evt_address = models.CharField(
"Evt address", max_length=255, null=True, blank=True)
evt_private_key = models.CharField(
"Evt private key", max_length=255, null=True, blank=True)
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
# deleted
class Meta:
db_table = "users"
pass
这是我的DRF更新模型视图:
class update_profile(RetrieveUpdateAPIView):
permission_classes = ()
authentication_classes = (FirebaseAuthentication,)
def update(self, request):
user_data = request.data
user = User.objects.get(uid=request.user.uid)
serializer = UpdateUserSerializer(user, data=user_data, partial=True)
if user_data == {}:
raise serializers.ValidationError({'code': 400, 'data': 'Invalid JSON object'})
for key_name in user_data:
if key_name not in ['email', 'uid', 'nickname', 'eth_address', 'eth_private_key', 'evt_address', 'evt_private_key']:
raise serializers.ValidationError({'code': 400, 'data': 'Invalid input ' + key_name})
if serializer.is_valid():
updated_user = serializer.save()
return JsonResponse({'code': 200,'data': updated_user.uid}, status=200)
else:
return JsonResponse({'code': 400,'errors':serializer.errors}, status=400)
我的意见如下:
{
"email": "test@gmail.com",
"uid": "dqwdqwd3123123",
"nickname":"Alan",
"eth_address": "dwdw",
"eth_private_key": "fwef",
"evt_address": "dwqdqwf",
"evt_private_key": "dwqdqqd"
}
我想在输入错误的情况下进行测试,因此我输入了错误的电子邮件,如ErrorEmail.com
,并正确验证:
{
"code": 400,
"errors": {
"email": [
"Enter a valid email address."
]
}
}
但是,当我尝试对其他类型(如
“昵称”:4123414)进行错误输入时,
即使在我设置昵称=models.CharField(“昵称”,max_length=255,null=True,blank=True)的模型中,它仍然通过验证。
我不知道为什么number的输入值通过了验证而没有引起错误。首先,我认为您在这里所做的大部分工作,比如检查正确的字段,都是由序列化程序本身完成的。您只需使用is\u valid(raise=True)
,django将负责返回正确的HTTP响应(如果您使用的是默认的django错误处理程序-阅读更多)
因此,您的视图应该是这样的:
类更新\u配置文件(RetrieveUpdateAppiview):
权限\类=()
身份验证\u类=(FirebaseAuthentication,)
def更新(自我,请求):
用户_data=request.data
user=user.objects.get(uid=request.user.uid)
serializer=UpdateUserSerializer(用户,数据=user\u数据,部分=True)
如果serializer.is_有效(raise_exception=True):
更新的\u user=serializer.save()
返回JsonResponse({'code':200,'data':updated_user.uid},status=200)
然而,我也认为尼克的例子实际上是正确的。数字可以转换为字符串,这就是序列化程序所做的->它将
4123414
更改为'4123414'
。仔细想想,这是一个完全正确的尼克。您应该尝试其他示例,比如为状态提供一个负数
,那么是否有任何方法可以检查它在输入json中是否实际上是一个字符串?由于前端有时会调用带有数字值的api,并且他们希望它返回错误一个确定的方法是编写自定义字段验证器,请阅读此处的更多内容:因此,如果不是is_instance(value,str)
,您必须做出一些会引发验证错误的事情。应该很简单。我不知道有什么更好的方法可以做到这一点,但听起来这可能是一个流行的问题,所以在引入自定义方法之前,我会做一些谷歌搜索。下面是一个类似的例子:我决定在视图端编写验证,因为序列化器中的所有内容都转换为字符串,但感谢您的解释