2012-10-30 38 views
1

我爲幾個關鍵模型和管理視圖設置了一個歷史記錄審計線索(django-simple-history)和paginate根據降序排序的(聚合)條目。問題是,我使用的方法是次優...Django - 對n個表排序的值進行分頁

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或其他方法來獲得相同的結果?

回答

1

所有型號都可以從一張表繼承(通過one-to-one鍵)。

通過這種方式,您可以通過django ORM使用基本表對此字段進行排序,稍後再獲取適當的實例。

請參閱that discussion以獲取最終實例的幫助。

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