我有一个查询,其中所有字段都是必需的。我想确保他们吃饱了。事实证明,有很多重复的代码。因此,我决定创建一个函数,将字段中的值传递给该函数。但是请求继续,而不是发送响应代码400。
我的views.py
def pay(request):
body = request.body.decode('utf-8')
if not body:
return JsonResponse({
'status': 'failed',
'errors': {
'code': 400,
'message': 'empty query'
},
})
body = json.loads(body)
phone = body.get('phone')
amount = body.get('amount')
merch_name = body.get('merchant_name')
#check_field(phone)
if not phone:
return JsonResponse({
'status': 'failed',
'errors': {
'code': 400,
'message': 'phone field is empty'
},
})
if not amount:
return JsonResponse({
'status': 'failed',
'errors': {
'code': 400,
'message': 'amount field is empty'
},
})
if not merch_name:
return JsonResponse({
'status': 'failed',
'errors': {
'code': 400,
'message': 'merch_name field is empty'
},
})
我的功能:
def check_field(field):
if not field:
logger.info('its work')
return JsonResponse({
'status': 'failed',
'errors': {
'code': 400,
'message': '{} field is empty'.format(field)
},
})
我该如何解决?
答案 0 :(得分:0)
我认为您的代码几乎正确,但是如果JsonResponse
函数调用的返回值不是check_field
,它应该返回一个None
对象。 (如果函数调用未返回任何值,则实际上返回None
)
def pay(request):
...
check_result = check_field(phone)
if check_result is not None:
return check_result
... (repeat ...)
无论如何,我建议您尝试使用Django REST Framework的Serializer。可以轻松解决这些参数检查问题。
答案 1 :(得分:0)
这是因为从被调用函数(check_field(phone)
)返回的值不会传播到调用方(pay
函数)之外。 pay
的责任是根据check_field
的收益做出决定。
您有两种选择:
将早期的long函数与辅助函数保持在一起,该辅助函数使您获得JsonResponse
的传递字段,例如:
def get_400_response(field_name):
return JsonResponse({
'status': 'failed',
'errors': {
'code': 400,
'message': f'{field_name} can not be empty'
},
})
并通过pay
函数,例如:
if not phone:
return get_400_response('phone') # note the `return` here
如果您想使用check_field
,则可以保持原样,然后从pay
检查返回值是否为JsonReponse
,如果返回,则返回将其保存为有效值:
phone = body.get('phone')
if isinstance(phone, JsonResponse):
return phone
另一种选择是引发异常,例如ValidationError
函数中的check_field
,而不是进行isinstance
检查,而是在try
-except
中进行处理,因此本质上是鸭式输入。
更好的方法: 最好汇总所有字段中的所有错误并将其作为单个响应发送,这样可以提高可用性。因此,您可以创建一个仅执行验证的功能(根据需要利用其他小功能),并发送验证后的数据或ValidationError
来获取无效数据,您可以从pay
处理它。
答案 2 :(得分:0)
请注意,您的check_field
不能按原样工作,因为field
是指值,而不是您传入的变量的名称。
使用异常可以避免代码重复:
from django.core.exceptions import ValidationError
def pay(request):
try
body = request.body.decode('utf-8')
if not body:
raise ValidationError('empty query')
body = json.loads(body)
for field_name in ['phone', 'amount', 'merchant_name']:
check_field(body, field_name)
except ValidationError as error:
return JsonResponse({
'status': 'failed',
'errors': {
'code': 400,
'message': error.message
},
})
def check_field(data, field_name):
if not data.get(field_name):
raise ValidationError('{} field is empty'.format(field_name)
我赞同@youngminz的建议,以研究Django REST Framework序列化程序。另外,您也可以使用常规的Django表单。
如果amount
是数字,而0是有效值,则必须使用data.get(field_name) is None
进行支票。