如何添加排序Django模型的异常?

时间:2011-09-29 09:40:58

标签: django django-models

我在python中有一行:

streams = Stream.objects.filter(info__isnull = False)\
        .order_by('-score', 'info__title')

我将它提供给RequestContext

c = RequestContext(request, {
    'online_streams': streams.filter(online = True),
    'offline_streams': streams.filter(online = False)
})

它按照得分和标题对约50行的表进行排序。这很好,但有一排我想总是成为顶级。只需事先获取它并将其从上面的行中过滤掉,然后单独将它提供给RequestContext将无法工作,因为我必须修改模板。此外,我可能会更改哪一行应该在后面,或者可能改为多行。

我是否可以插入一个过滤器参数,说明行中的内容“按分数排序所有行然后标题,除了行ID 8,它应该始终是顶部”?或者我可以在过滤后手动更改QuerySet的顺序吗?

感谢您的任何建议

2 个答案:

答案 0 :(得分:0)

您可以覆盖模型管理器方法:

类MyManager(models.Manager):

def filter(self, *args, **kwargs):
    return super(MyManager, self).filter(*args, **kwargs).exclude(id=8).order_by(...)

然后在模型中

class Stream(models.Model):
    ...
    objects = MyManager()

EDIT 要确保它包含在内,您可以查询:

from django.db.models import Q
return super(MyManager, self).filter(Q(id=8) | Q(*args, **kwargs)).order_by(...)

答案 1 :(得分:0)

我找不到使用查询集来执行此操作的方法,因此我最终将查询集转换为列表并使用魔术比较函数对其进行排序。它最终看起来像这样:

神奇的分拣机,检查应该卡在“顶部”的名称:

# Comparison magic
def __cmp__(self, other):
    # On top
    if self.name in stream_ontop:
        return 1
    if other.name in stream_ontop:
        return -1

    # Score
    if self.score > other.score:
        return 1
    if self.score < other.score:
        return -1

    # Title alphabetical
    if self.info.title > other.info.title:
        return -1
    if self.info.title < other.info.title:
        return 1

    return 0

然后我从我的模型类

中取出并对它们进行了分类
# Custom sorting
@staticmethod
def getAllSorted(online):
    streams = list(Stream.objects.filter(online=online, info__isnull=False))
    streams.sort(key=None, reverse=True)

    return streams