Python Django序列化程序从post访问json数据(字符串索引必须是整数)
我正在尝试为register post请求的验证创建序列化程序 通过POST请求发送到API的json:Python Django序列化程序从post访问json数据(字符串索引必须是整数),python,django,validation,django-rest-framework,serialization,Python,Django,Validation,Django Rest Framework,Serialization,我正在尝试为register post请求的验证创建序列化程序 通过POST请求发送到API的json: { "username": "dat@icts.vn", "password": "123456", "confirm_password": "123456" } 用于验证的我的序列化程序: class RegisterSerializer(serializers.Serializer): username = serializers.EmailField(
{
"username": "dat@icts.vn",
"password": "123456",
"confirm_password": "123456"
}
用于验证的我的序列化程序:
class RegisterSerializer(serializers.Serializer):
username = serializers.EmailField(required=True)
password = serializers.CharField(required=True)
confirm_password = serializers.CharField(required=True)
def validate_username(self, username):
existing_email = User.objects.filter(email=username).first()
if existing_email:
raise serializers.ValidationError("Email already registered")
return username
def validate_confirm_password(self, data):
if data['password']:
if data['confirm_password'] != data['password']:
raise serializers.ValidationError("Confirm password not match password")
return data['confirm_password']
我的视图寄存器功能:
@csrf_exempt
@require_http_methods(["POST"])
def register(request):
received_json_data=json.loads(request.body)
valid_ser = RegisterSerializer(data=received_json_data)
if valid_ser.is_valid():
post_username = received_json_data["username"]
post_password = received_json_data["password"]
user = User.objects.create_user(username=post_username,password=post_password)
user.save()
refresh = RefreshToken.for_user(user)
content = {
'refresh': str(refresh),
'access': str(refresh.access_token),
}
return JsonResponse(content)
else:
return JsonResponse({'code':'400','errors':valid_ser.errors}, status=400)
发送POST请求时,出现以下错误:
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
web_1 | response = get_response(request)
web_1 | File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 115, in _get_response
web_1 | response = self.process_exception_by_middleware(e, request)
web_1 | File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 113, in _get_response
web_1 | response = wrapped_callback(request, *callback_args, **callback_kwargs)
web_1 | File "/usr/local/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
web_1 | return view_func(*args, **kwargs)
web_1 | File "/usr/local/lib/python3.6/site-packages/django/views/decorators/http.py", line 40, in inner
web_1 | return func(request, *args, **kwargs)
web_1 | File "/app/api/views.py", line 84, in register
web_1 | if valid_ser.is_valid():
web_1 | File "/usr/local/lib/python3.6/site-packages/rest_framework/serializers.py", line 235, in is_valid
web_1 | self._validated_data = self.run_validation(self.initial_data)
web_1 | File "/usr/local/lib/python3.6/site-packages/rest_framework/serializers.py", line 430, in run_validation
web_1 | value = self.to_internal_value(data)
web_1 | File "/usr/local/lib/python3.6/site-packages/rest_framework/serializers.py", line 489, in to_internal_value
web_1 | validated_value = validate_method(validated_value)
web_1 | File "/app/api/views.py", line 49, in validate_confirm_password
web_1 | if data['password']:
web_1 | TypeError: string indices must be integers
web_1 | [05/Sep/2019 04:59:33] "POST /api/register HTTP/1.1" 500 99431
似乎我无法用序列化器中的密钥访问json数据变量,我有点被困在这个问题上。任何帮助都将非常感谢。它类似于
validate\u username(self,username)
方法,validate\u confirm\u password(self,data)
中的data
参数实际上是密码值,它是一个字符串
Ref您应该将函数
validate\u confirm\u password
重命名为validate
如前一个响应中所述,validate{field_name}
用作并将接收/返回实际字段的值,而不是当前数据
相反,您要做的是使用验证
(例如)
在您的情况下,这将给出:
class RegisterSerializer(serializers.Serializer):
username = serializers.EmailField(required=True)
password = serializers.CharField(required=True)
confirm_password = serializers.CharField(required=True)
def validate_username(self, username):
existing_email = User.objects.filter(email=username).first()
if existing_email:
raise serializers.ValidationError("Email already registered")
return username
def validate(self, data):
if data['password']:
if data['confirm_password'] != data['password']:
raise serializers.ValidationError("Confirm password not match password")
return data
在
validate\u fieldname(self,fieldvalue)
中,您将获得要验证的字段的实际值
由于您已使用username值直接过滤validate\u username
方法中的现有记录
但是在validate\u confirm\u password
方法中,您试图验证密码,这是不正确的方法
要根据完整的请求进行验证,您可以使用validate
方法
def validate(self, data):
username = data["username"]
password = data["password"]
confirm_password = data["confirm_password"]
# your validation logic
正如上面所说:
我们对初始数据进行了两级验证:
:
您可以通过向序列化程序子类添加。validate\uu
方法来指定自定义字段级验证。这些方法类似于Django表单上的。clean
方法
示例:
from rest_framework import serializers
class BlogPostSerializer(serializers.Serializer):
title = serializers.CharField(max_length=100)
content = serializers.CharField()
def validate_title(self, value):
"""
Check that the blog post is about Django.
"""
if 'django' not in value.lower():
raise serializers.ValidationError("Blog post is not about Django")
return value
from rest_framework import serializers
class EventSerializer(serializers.Serializer):
description = serializers.CharField(max_length=100)
start = serializers.DateTimeField()
finish = serializers.DateTimeField()
def validate(self, data):
"""
Check that start is before finish.
"""
if data['start'] > data['finish']:
raise serializers.ValidationError("finish must occur after start")
return data
注意:如果在序列化程序上使用参数required=False声明了
,则如果未包含该字段,则不会执行此验证步骤
:
要执行需要访问多个字段的任何其他验证,请将名为.validate()
的方法添加到序列化程序子类中。此方法采用单个参数,即字段值字典。如果需要,它应该引发serializers.ValidationError,或者只返回已验证的值
示例:
from rest_framework import serializers
class BlogPostSerializer(serializers.Serializer):
title = serializers.CharField(max_length=100)
content = serializers.CharField()
def validate_title(self, value):
"""
Check that the blog post is about Django.
"""
if 'django' not in value.lower():
raise serializers.ValidationError("Blog post is not about Django")
return value
from rest_framework import serializers
class EventSerializer(serializers.Serializer):
description = serializers.CharField(max_length=100)
start = serializers.DateTimeField()
finish = serializers.DateTimeField()
def validate(self, data):
"""
Check that start is before finish.
"""
if data['start'] > data['finish']:
raise serializers.ValidationError("finish must occur after start")
return data
因此,您应该在validate(data)
方法中验证confirm\u password
,您可以这样访问数据:
def validate(data):
confirm_password = data.get('confirm_password', None)
password = data.get('password', None)
# don't forget to return validated data
return data
您在哪里呼叫validate\u confirm\u password
?感谢您的解释,我直到现在才知道,我还必须更改ValidationError,否则它将显示错误字段属于非字段错误,这不是正确的响应。ValidationError({'confirm_password':['confirm password not match password']})