从Django REST中的函数返回JsonResponse

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从Django REST中的函数返回JsonResponse相关的知识,希望对你有一定的参考价值。

我有一个查询,其中所有字段都是必填字段。我想确保他们吃饱了。事实证明,有很多重复的代码。因此,我决定创建一个函数,将字段中的值传递给该函数。但是请求继续,而不是发送响应代码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)
            },
        })

我该如何解决?

答案

我认为您的代码几乎正确,但是如果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。这使这些参数检查问题变得容易。

另一答案

这是因为从被调用函数(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处理它。
另一答案

请注意,您的check_field无法按原样工作,因为field引用的是值而不是您传入的变量的名称。

以上是关于从Django REST中的函数返回JsonResponse的主要内容,如果未能解决你的问题,请参考以下文章

从 Django REST Framework 中的 APIView 中获取完整的请求 URL

尝试覆盖django rest框架中的update方法,以在更新后返回整个查询集

Django rest框架:如何全局更改错误响应格式

从 Django django-rest-framework 视图有条件地返回 JSON 或 HTML 响应

从 Django Rest Framework 中的令牌获取经过身份验证的用户

从 WCF REST Web 服务返回包装在回调函数中的 JSON