我想知道如何使用装饰器来验证django中的JSON请求。目前我有validations.py
文件,函数validate
如果请求有效则返回True
,否则返回False
。
我目前的实施方式如下:
validations.py:
def validate(request):
flag = True
.... # Actual logic for validating request and
# sets flag to True/False
return flag
views.py
from validations import validate
def authenticate_user(request):
if validate(request):
.......
# executes further logic based on request
# This checks if right access is present in Database
# for the user or not. And hence I want to access request variable as it is
else:
return "Bad Request"
我想知道我在这里如何使用装饰器并做这样的事情:
@validate
def authenticate_user(request):
.......
# executes further logic based on request
# This checks if right access is present in Database
# for the user or not. And hence I want to access request variable as it is
validate
函数应该直接将"Bad Request"
返回给客户端,如果验证因任何原因而失败,则应该执行正常的代码执行。
答案 0 :(得分:1)
您可以执行类似
的操作import inspect
def decorator(f):
def requestchecker(request, *args):
if not validate(request):
raise ValueError("bad request")
return f(request, *args)
return requestchecker
@decorator
def djangoview(request, x, y):
# do stuff
当然,应该稍微修改实际代码,具体取决于您是使用命名还是位置等...
答案 1 :(得分:1)
第一点:你的验证函数不应该返回一个布尔标志(它不会告诉你什么出错),而是引发异常(可能是ValidationError
或你自己的自定义异常类型,具体取决于你的'确切地重新验证 - 调用者负责捕获它并做适当的事情。
第二点:您的视图不应返回文字字符串“Bad request”,它应返回带有相应状态代码的HttpResponse
。 FWIW,“错误请求”的http状态代码是400,但它有一个非常明确的语义(强调是我的):
由于格式错误,服务器无法理解该请求 语法即可。客户端不应该重复请求 修改
JSON有效负载中缺少的字段不是“格式错误的语法”。
至于如何使用装饰器将相同的验证函数应用于多个视图函数,假设validate
函数引发ValidationError
(或您定义的任何更具体的异常类型):
def require_validation(func):
def wrapper(request, *args, **kwargs):
try:
validate(request)
except ValidationError as e:
# logging the exception might be useful
# and you may want to select the exact
# response status depending on the exact error
# Also if your client posted some json stuff
# chances are it expects a json content-type and body
return HttpResponse("Bad request", status=400)
return function(request, *args, **kwargs)
wrapper.__doc__ = function.__doc__
wrapper.__name__ = function.__name__
return wrapper
@require_validation
def myview(request, ...):
#...
答案 2 :(得分:0)
你也可以这样做..
from yourmodel.models import Admin
from django.http import HttpResponseRedirect
def admin_required(function):
"""
@admin_required
def dashboard(request):
#do_stuff
"""
def wrap(request, *args, **kwargs):
if request.user.is_authenticated() and \
Admin.objects.filter(user=request.user).exists():
return function(request, *args, **kwargs)
else:
return HttpResponseRedirect('/')
wrap.__doc__ = function.__doc__
wrap.__name__ = function.__name__
return wrap