Python django中验证GET参数的正确方法

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

我正在建立一个使用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  = 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()")

 ...