我正在使用Django DRF构建api。该API工作正常。但是它针对不同类型的错误生成不同的响应。假设,如果我添加了用户注册功能。我正在使用serializers.ValidationError
函数处理序列化程序中的一些错误。但这改变了对不同错误的响应。我只希望以{"message": "reason for the error", "error": 1}
的标准方式进行回复。我不想硬编码它。我的意思是我已经使用了多种功能,所以我必须对所有地方进行硬编码。因此,有没有更好的解决方案,例如向序列化器添加函数并从中生成响应?
class UserSerializer(serializers.ModelSerializer):
confirm_password = serializers.CharField(max_length=50, required=True, validators=[password_check], write_only=True)
password = serializers.CharField(max_length=50, required=True, validators=[password_check])
Id = serializers.CharField(max_length=100, required=False, allow_blank=True)
user_type = serializers.CharField(max_length=30, required=True, write_only=True)
email = serializers.EmailField(required=True)
def validate_username(self, username):
if User.objects.filter(username=username):
raise serializers.ValidationError('Username already chosen!')
if len(username) < 8:
raise serializers.ValidationError('Username min length is 8')
return username
def validate_email(self, email):
try:
validate_email(email)
except ValidationError:
raise serializers.ValidationError('Enter a valid email')
if User.objects.filter(email=email):
raise serializers.ValidationError('Email already chosen!')
return email
def validate(self, attrs):
key = 0
try:
if models.Profile.objects.filter(userid=attrs['Id']).exists() and attrs['Id'] != '':
raise serializers.ValidationError('UserId already chosen')
if attrs['Id'] == '':
key=1
except KeyError:
key=1
if key == 1:
if attrs['user_type'] != 'Admin' and attrs['user_type'] != 'AdminCoordinate':
raise serializers.ValidationError("UserId can\'t be empty!")
else:
attrs['user_id'] = ''
if attrs['password'] != attrs['confirm_password']:
raise serializers.ValidationError('Enter same passwords both the times!')
return attrs
class Meta:
model = User
fields = ('pk', 'username', 'password', 'email', 'confirm_password', 'Id', 'user_type')
read_only_fields = ('pk',)
答案 0 :(得分:0)
对此没有简单的方法,至少没有您想要的那么简单。
您也许可以编写一个中间件来处理此问题,但这仍然有些混乱,因为您必须检查响应中的每个错误并覆盖它们。我真的不建议这样做。
您还可以为每个序列化器使用Meta类,但是仍然需要为每个序列化器添加一些代码。
示例:
class SomeSerializer(ModelSerializer):
class Meta:
model = SomeMode
extra_kwargs = {"SomeField": {"error_messages": {"required": "This field can not be empty!"}}}
最后,我认为您最终将对大多数验证进行硬编码。
答案 1 :(得分:0)
感谢@ Navid2zp的回答。这太酷了。但是它不能处理所有异常。我仔细阅读了文档,发现了一种处理所有异常的简单通用方法。我编写了一个简单的代码,使用该代码一次只能显示一个错误,而不是显示多个错误。这是我的编码方式:
from rest_framework.views import exception_handler
def custom_exception_handler(exc, content):
response = exception_handler(exc, content) # Get the response Header.
error = ''
for key, value in response.data.items():
if isinstance(value, str):
error = value
else:
error = value[0]
if key == 'non_field_errors':
custom_response = {'message': error, 'error': 1}
else:
custom_response = {'message': key + ", " + error, 'error': 1}
break
response.data = custom_response
return response
我写了一个自定义的异常处理程序来显示消息,并且该类也必须添加到REST_FRAMEWORK
内的settings.py文件中。
'EXCEPTION_HANDLER': 'project_name.utils.custom_exception_handler',