如何确保查询集将由有效字段 - django排序

时间:2010-03-04 22:31:49

标签: django

这是模板标记代码的一部分,其中qs是查询集。

def foo(qs):
    ...
    context['key'] = qs.order_by('an_invalid_field_coming_from_user')

如何在代码执行超出模板标记范围之前检查查询集是否将按有效字段排序,而不是强制进行评估?

由于未评估查询集,因此代码不会引发错误。 qs.exists()不是答案,因为它将在不进行排序的情况下执行查询。

编辑:请注意,查询可能比我的编辑前简单示例Foo.objects.all()更复杂,例如,它可能包含导致联接的extra()方法

4 个答案:

答案 0 :(得分:3)

您可以通过运行str(qs.query)强制查询集进行验证。此时,您可以捕获异常,而不会导致它查询数据库。

try:
    str(qs.order_by('some_field').query)
except FieldError:
    # bad order_by
    pass

答案 1 :(得分:2)

如果你真的反对捕捉异常(你不应该这样做),你可以这样做:

if context['key'] in [field.name for field in Foo._meta.fields]:
    qs = Foo.objects.all().order_by(context['key'])

答案 2 :(得分:1)

order_by()与不存在的字段一起使用会抛出django.core.exceptions.FieldError。只需捕获并向用户报告错误。

答案 3 :(得分:1)

我不确定这是一个好主意,因为这里可能存在安全问题。我认为这会有效,但我没有Django的副本来测试当下。我很确定当你这样做时会抛出异常,但是如果你不想抓住它或者先发制人地检查它应该有效:

if hasattr(Foo, "fieldname") and isinstance(getattr(Foo, "fieldname"), models.Field):
    print "Safe field"
else:
    print "Invalid field"