Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在Django中订购反向外键?_Python_Django_Sorting - Fatal编程技术网

Python 如何在Django中订购反向外键?

Python 如何在Django中订购反向外键?,python,django,sorting,Python,Django,Sorting,我们正在使用Django 1.4。我们有一个classA,它有一个与之相关的class历史。可以有许多历史对象与A的任何单个对象相关 History类具有指向其他类的外键,例如BusinessUnit 我想按最后一个历史对象(如果有)对A的对象进行排序(按history.logged\u排序,位于) 我试过使用order\u by('history\u business\u unit'),但它不能正常工作。是否可以使用数据库进行这样的排序,还是必须使用Python进行排序?如果可能的话,我更喜欢

我们正在使用Django 1.4。我们有一个class
A
,它有一个与之相关的class
历史。可以有许多历史对象与
A
的任何单个对象相关

History
类具有指向其他类的外键,例如
BusinessUnit

我想按最后一个历史对象(如果有)对
A
的对象进行排序(按
history.logged\u排序,位于


我试过使用
order\u by('history\u business\u unit')
,但它不能正常工作。是否可以使用数据库进行这样的排序,还是必须使用Python进行排序?如果可能的话,我更喜欢使用数据库进行排序。

您必须注释最大相关日期,过滤最大日期等于历史日期的历史对象,并按
业务单位
属性排序:

from django.db.models import Max, F

a = A.objects.annotate(last_date=Max('history_set__logged_at'))\
    .filter(history_set__logged_at=F('last_date'))\
    .order_by('history_set__business_unit__<attribute>')
从django.db.models导入最大值,F
a=a.objects.annotate(last\u date=Max('history\u set\u logged\u at'))\
.filter(历史记录\u设置\u记录\u at=F('last\u date'))\
.order\u by('history\u set\u business\u unit\u')

这样,对于每个
A
对象,您可以过滤最后一个
历史
相关对象,并在相关的
业务单元
上排序。仅使用
history\u set\u business\u unit
将根据业务单元的id进行订购,因此对于任何有意义的订购,您需要决定要订购的
business\u unit
的哪个属性

最后我用Python排序,使用list.sort:

def human_key(key):
    parts = re.split('(\d*\.\d+|\d+)', key.lower())
    return tuple((e.swapcase() if i % 2 == 0 else float(e)) for i, e in enumerate(parts))

if (ordered in ["unregistered_business_unit", "unregistered_operational_unit", "unregistered_date"]):
    a_list = list(a_list)
    for a in a_list:
        a_history = list(a.history.all().order_by('-logged_at'))
        if (len(a_history) > 0):
            a.last_a_history = a_history[0]
        else:
            a.last_a_history = None
    if (ordered == "unregistered_business_unit"):
        a_list.sort(key=lambda a: (a.last_a_history.business_unit.description.lower() if ((a.last_a_history) and (a.last_a_history.business_unit)) else None, a.last_a_history.business_unit.identifier if ((a.last_a_history) and (a.last_a_history.business_unit)) else None, human_key(a.last_a_history.operational_unit.identifier) if ((a.last_a_history) and (a.last_a_history.operational_unit)) else None, a.mac_address), reverse=reverse_flag)
    elif (ordered == "unregistered_operational_unit"):
        a_list.sort(key=lambda a: (human_key(a.last_a_history.operational_unit.identifier) if ((a.last_a_history) and (a.last_a_history.operational_unit)) else None, a.last_a_history.business_unit.description.lower() if ((a.last_a_history) and (a.last_a_history.business_unit)) else None, a.last_a_history.business_unit.identifier if ((a.last_a_history) and (a.last_a_history.business_unit)) else None, a.mac_address), reverse=reverse_flag)
    elif (ordered == "unregistered_date"):
        a_list.sort(key=lambda a: (a.last_a_history.logged_at if (a.last_a_history) else pytz.utc.localize(datetime(MINYEAR, 1, 1)), a.mac_address), reverse=reverse_flag)

“不能正常工作”是什么意思?到底发生了什么,这与您预期的情况有何不同?@DanielRoseman我认为它是按随机历史对象排序的,还是按pk排序的。我想根据History.logged_at(或第一个具有反向历史记录的对象。logged_at)按最后一个历史对象的业务单元排序。如何按最后一个历史对象的业务单元排序?@Uri:Ah,那么您想按最后一个
历史对象的
业务单元
为每个
A
排序?如果
business\u unit
确实是一个外键,那么仅按
'history\u business\u unit'
排序将按
id
排序。如果您想要任何有意义的排序,您应该按照
业务单元
的属性进行排序。是的,但是可以有许多与
A
相关的历史对象。他们每个人都有一个业务部门的外键。我想按最后一个历史对象的业务部门进行订购。按“历史\业务\单位”排序不是按上一个历史对象的业务单位排序。谢谢,但问题是可能有
A
的对象没有任何历史对象,如果按上一个\日期筛选,则可能没有。我现在检查了您的解决方案,它筛选出了4个对象(共68个)而且它不能正确地对对象进行排序。