我正在构建一个使用django模板/动态页面的社交网站(没有SPA技术)。 我有一些调用用户新闻源或新消息的ajax调用。 示例GET 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不会崩溃。目前它崩溃了,因为在Feed模型中,函数执行此操作:
@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()转换上的异常来解决这个问题:
def check(request):
last_feed = request.GET.get('last_feed')
try:
feed_source = int(request.GET.get('last_feed'))
except ValueError:
return HttpResponse(0)
我的问题是django推荐的最佳解决方法是什么? 我知道django有特殊的支持表格验证。但这在这里看起来并不合适,因为GET调用更多的是api而不是形式,因此为这些GET参数定义表单似乎是个坏主意。
由于
答案 0 :(得分:1)
您真正需要的只是表单字段,这些表单字段会为您进行所有基本验证。 如果您需要自定义验证,则可以编写自己的验证器,甚至可以编写自己的自定义表单字段。
要单独使用不带表单的字段,您可以这样做,例如:
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)
这将为您节省一个窗体类。但我认为为此创建django表单并不难看。对于这个问题来说有点太多了,但是恕我直言,没什么好担心的。
拥有表单的优点是,您可以在api调用中声明所需的字段,并且可以一次检查所有字段,然后查看is_valid()
的结果。
我希望这会有所帮助。
答案 1 :(得分:0)
您还可以使用django Validator,
带有值并在不符合某些条件的情况下引发
ValidationError
的可调用对象。
在您的特定情况下,可以使用validate_slug()
的组合-仅在传递的输入由字母,数字,下划线或连字符组成的情况下,才会组合ValidationError
和{{1 }}以这种方式起作用:
int()