繁体   English   中英

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

[英]How to order a reverse foreign key in Django?

我们正在使用Django 1.4。 我们有一个班级A ,这个班级有一个与之相关的History 可以有许多与A单个对象相关的History对象。

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

我想按最后一个历史记录对象(如果有的话)对A的对象进行排序(按History.logged_at排序)。

我尝试使用order_by('history__business_unit') ,但无法正常工作。 是否可以使用数据库进行此类排序,还是必须使用Python进行排序? 如果可能,我更喜欢使用数据库进行排序。

您将必须注释最大相关日期,过滤历史记录对象(其中最大日期等于历史记录的日期),并按business_unit属性排序。

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>')

这样,对于每个A对象,您将筛选出与History相关的最后一个对象,并在关联的business_unit上进行排序。 仅使用history_set__business_unit将按业务单位的ID进行排序,因此对于任何有意义的排序,您都需要确定要订购的business_unit属性。

最终,我使用list.sort与Python进行了排序:

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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM