2016-12-15 65 views
0

我是Python,Django和Django Rest Framework的新手 - 虽然我喜欢学习曲线!当参数丢失Django Rest框架时抛出异常

我想知道当没有提供API参数时引发异常的标准(最常见)方式是什么?

显然如果条件在视图的身体是不是要走的路。有可以传递参数名称的装饰器吗?

# urls.py 

    urlpatterns = [ 
    url(r'test', test), 
    url(r'errand/make', errand.make), 
    url(r'errand/preview', errand.preview) 
] 

# views/errand.py 

@api_view(['GET']) 
@renderer_classes((JSONRenderer,)) 
def preview(request): 
    e = Errand.objects.get(pk=request.GET['errand_id']) 
    return Response({'data': e.get_preview_data()}) 

为了此行

e = Errand.objects.get(pk=request.GET['errand_id']) 

要运行良好,errand_id需求可用。我如何检查某些请求键

回答

1

对于参数没有默认值的任何函数调用,您将得到TypeError

只要您没有传入默认值,即使参数在函数内部不被使用,您也会得到一个异常。

在你的榜样,因为你使用dict.get,默认情况下,如果关键是没有找到它会返回None

如果你想要一个异常那里,你可以直接尝试访问关键,这将导致KeyError当它没有被发现时。像这样:

... 
e = Errand.objects.get(pk=request['errand_id']) 
... 

否则另一个解决方案是创建表示该请求的所期望的结构的模式,并验证在函数或使用装饰该请求。

像这样的事情将是一个开始:

def errand_id_required(func): 
    def func_wrapper(request): 
     if not request.get('errand_id', False): 
      raise KeyError('errand_id not present in request') 
     return func(request) 
    return func_wrapper 

@errand_id_required 
def preview(request): 
    e = Errand.objects.get(pk=request.GET['errand_id']) 
    return Response({'data': e.get_preview_data()}) 

我一般只做到这一点,如果我有验证字典架构的复杂的方式,否则这是非常矫枉过正写一个装饰检查单个密钥。

你可以尝试PyPI上的架构库,并定义是这样的:

import schema 

errand_schema = { 
    schema.Optional('some_key'): str, 
    'id': int, 
    'errand_id': int, 
} 
Errand = schema.Schema(errand_schema, ignore_extra_keys=True) 

,你可以使用Errand.validate(request)而不是我把装饰的if.. raise KeyError的。

但我会留给你决定...

+0

当然 - 这将推断从url的params权利?你可以看看我的编辑。它可能会清理一些事情。 –

+0

如果存在'errand_id'但是'Errand.objects.get(pk = request.GET ['errand_id'])'会产生'Errand.DoesNotExist'? – Qubad

+0

为什么它会将异常的属性作为异常提升? –