Python django中验证GET参数的正确方法
我正在建立一个使用django模板/动态页面(没有SPA技术)的社交网站。 我有一些ajax调用来检查用户的新闻提要或新消息。 示例获取这些外观的web请求,如下所示:Python django中验证GET参数的正确方法,python,django,Python,Django,我正在建立一个使用django模板/动态页面(没有SPA技术)的社交网站。 我有一些ajax调用来检查用户的新闻提要或新消息。 示例获取这些外观的web请求,如下所示: GET /feeds/check/?last_feed=3&feed_source=all&_=1500749662203 HTTP/1.1 以下是我在视图中接收它的方式: @login_required @ajax_required def check(request): last_feed = r
GET /feeds/check/?last_feed=3&feed_source=all&_=1500749662203 HTTP/1.1
以下是我在视图中接收它的方式:
@login_required
@ajax_required
def check(request):
last_feed = request.GET.get('last_feed')
feeds = Feed.get_feeds_after(last_feed)
这一切都是可行的,但我想保护它,这样当恶意用户将get参数设置为last_feed=“123malicious4556”时,函数get_feeds_after不会崩溃。当前它崩溃,因为在提要模型中,函数执行以下操作:
@staticmethod
def get_feeds_after(feed):
feeds = Feed.objects.filter(parent=None, id__gt=float(feed))
return feeds
并因错误而崩溃:
ValueError at /feeds/check/
invalid literal for float(): 2fff2
我目前通过直接对GET变量执行检查并处理int()转换异常来解决此问题:
我的问题是django推荐的解决这个问题的最佳方法是什么?
我知道django有特殊的支持表单验证。但是这在这里似乎不太正确,因为GET调用更像是一个api而不是表单,所以为那些GET参数定义表单似乎不是一个好主意
谢谢您真正需要的是表单字段,它为您执行所有基本验证。 如果您需要自定义验证,您可以编写自己的验证程序,或者更好地编写自己的自定义表单字段 要单独使用字段而不使用表单,您可以这样做,例如:
evalType=forms.CharField().clean(request.GET.GET('eval-type'))
因为这种方式调用不太人性化,我更喜欢编写一个函数来处理它:
def cleanParam(params, paramName, FieldType, *args, **kwargs):
field = FieldType(*args, **kwargs)
cleaned = field.clean(params.get(paramName))
return cleaned
我们采用这种方式:
evalType = cleanParam(request.GET, 'eval-type', forms.CharField)
from django.core.validators import validate_slug
...
last_feed = request.GET.get("last_feed", "")
try:
validate_slug(last_feed)
last_feed = int(last_feed)
...
except ValueError:
print("invalid literal passed to int()")
except ValidationError:
print("invalid input passed to validate_slug()")
...
这将为您节省一个表单类。但我不认为为它创建django表单是非常丑陋的。对这个问题来说有点太多了,但对我来说没什么大不了的
拥有表单的好处是,您可以声明api调用中需要的字段,并可以一次检查所有字段,然后查看的结果是否有效()
我希望这有帮助。您也可以使用
一个可调用函数,它接受一个值并在不满足某些条件时引发一个ValidationError
在您的特定情况下,您可以使用组合的validate_slug()
-只有当传递的输入由字母、数字、下划线或连字符组成时,才不会引发ValidationError
-和int()
函数以这种方式:
evalType = cleanParam(request.GET, 'eval-type', forms.CharField)
from django.core.validators import validate_slug
...
last_feed = request.GET.get("last_feed", "")
try:
validate_slug(last_feed)
last_feed = int(last_feed)
...
except ValueError:
print("invalid literal passed to int()")
except ValidationError:
print("invalid input passed to validate_slug()")
...