【问题标题】:django order_by FieldError exception can not be catcheddjango order_by FieldError 异常无法捕获
【发布时间】:2011-08-24 10:20:38
【问题描述】:
from django.core.exceptions import FieldError

#This is a method of a class
def _order_item_list(self, item_list, order_items_by, previous_order_by):
    if order_items_by == previous_order_by:
        order_items_by = '-' + order_items_by 

    try:
        result = item_list.order_by(order_items_by)
    except FieldError:
        result = item_list

    return result, order_items_by

现在,当我按照生成的链接按有效字段排序时,一切正常。当我编辑一个链接并添加一些用于排序的虚拟字段名时,它应该被这个异常捕获并且应该返回原始列表。但它没有发生,相反我总是从 django 得到一个 FieldError。

FieldError at ...

无法将关键字 u'fgsdffds' 解析为字段。选择是:...

【问题讨论】:

    标签: django exception


    【解决方案1】:

    没有捕捉到异常的原因是QuerySet还没有被评估。

    要验证用于模型字段或order_by 值的任意(用户指定)值,只需检查该模型是否具有该名称的字段。

    例如,假设您有一个名为 Ticket 的模型和一个名为 field_name 的任意 GET 参数。以下是在views.py 中创建有效QuerySet 的方法:

    from django.db.models import FieldDoesNotExist
    from myapp.models import Ticket
    
    def index(request):
        default_field = 'id'
        field_name = request.GET.get('field_name', default_field)
    
        try:
            Ticket._meta.get_field_by_name(field_name)
        except FieldDoesNotExist:
            field_name = default_field
    
        tickets = Ticket.objects.all().order_by(field_name)
        return ...
    

    【讨论】:

    • 降序情况不适用于此-field_name
    • 在 Django 1.10+ 中,get_field_by_name(name) 已弃用。请改用get_field(name)
    • 问题是如果您按降序排列'-field_name' 或按外键'field__fkname' 订购,您必须调整输入。还有其他方法可以捕捉到这些吗?
    【解决方案2】:

    这意味着存在拼写错误,或者异常发生在其他地方。插入调试行:

     import pdb; pdb.set_trace()
    

    在 try-except 之前,看看代码是如何执行的。尝试使用PUDBIPDB 调试器,而不是标准的调试器。当您拥有调试器并且可以准确地看到问题所在时,许多问题就会消失。

    【讨论】:

    • 你是绝对正确的。稍后会引发异常,这肯定是因为 django 的优化以避免许多单独的 db 操作...谢谢
    【解决方案3】:

    我遇到了同样的问题,肯定是因为后来出现了异常。为了在 try-catch 块中引发异常,我按以下方式修改了代码:

    try:
        result = item_list.order_by(order_items_by)
        **result = list(result)**
    except FieldError:
        result = item_list
    

    这对我有用。

    【讨论】:

    • 这是个坏主意,因为 list() 会强制评估 QuerySet 并将其加载到内存中。请参阅我发布的答案以获得更好的解决方案。
    猜你喜欢
    • 2010-10-29
    • 1970-01-01
    • 2012-06-09
    • 2021-10-09
    • 2021-09-17
    • 2021-10-03
    • 2018-02-04
    • 2018-02-04
    相关资源
    最近更新 更多