我为一些关键模型设置了一个小历史审计跟踪(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或同样结果的替代方法?
答案 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。