Django - 对n个表排序值进行分页

时间:2012-10-30 08:27:12

标签: django sorting

我为一些关键模型设置了一个小历史审计跟踪(django-simple-history),并为paginate设置了一个管理视图,这些条目是按降序排序的(聚合的)条目。问题是,我使用的方法不是最理想的......

historical_foo = Foo.history.all()
historical_bar = Bar.history.all()
historical_qux = Qux.history.all()

#sort the aggregate by modified date
result_list = sorted(chain(historical_foo, historical_bar, historical_qux), key=attrgetter('history_date'), reverse=True)

paginator = Paginator(result_list, 100)

try:
    result = paginator.page(page_num)
    #...

这肯定不会很好地扩展,因为这些表变大了。有没有办法将聚合和排序逻辑推入Django / DB或同样结果的替代方法?

2 个答案:

答案 0 :(得分:2)

您可以使用contenttypes将所有内容保存在一个表中:

from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic

class HistoryRecord(models.Model):
    history_date = models.DateTimeField()
    history_id = models.PositiveIntegerField()
    content_type = models.ForeignKey(ContentType)
    content = generic.GenericForeignKey('content_type', 'history_id')

然后你需要创建那些:

poll = Poll.history.all()[0]
record = HistoryRecord(content=poll, history_date=poll.history_date)
record.save()

或者你可以继承HistoricalRecords

class IndexedHistoricalRecords(HistoricalRecords):
    def create_historical_record(self, instance, type):
        history_user = getattr(instance, '_history_user', None)
        manager = getattr(instance, self.manager_name)
        attrs = {}
        for field in instance._meta.fields:
            attrs[field.attname] = getattr(instance, field.attname)
        content = manager.create(history_type=type, history_user=history_user, **attrs)
        record = HistoryRecord(content=poll, history_date=poll.history_date)
        record.save()

然后你可以查询一个表:

result_list = HistoryRecord.objects.all()
paginator = Paginator(result_list, 100)
...

答案 1 :(得分:1)

所有模型都可以从一个表(通过one-to-one键)继承。

通过这种方式,您可以使用基表在此字段上按django ORM进行排序,然后再获取适当的实例。

有关获取最终实例的帮助,请参阅that discussion