2017-01-17 43 views
0

使用GenericRelation一個ForeignKey Django的查詢緩存來Record點地圖到Person S,我有以下的代碼,它工作正常,但有一個性能問題,我試圖解決:通過在GenericRelation

models.py中

class RecordX(Record): # Child class 
    .... 

class Record(models.Model): # Parent class 
    people = GenericRelation(PersonRecordMapping) 

    def people_all(self): 
     # Use select_related here to minimize the # of queries later 
     return self.people.select_related('person').all() 

    class Meta: 
     abstract = True 

class PersonRecordMapping(models.Model): 
    person = models.ForeignKey(Person) 
    content_type = models.ForeignKey(ContentType) 
    object_id = models.PositiveIntegerField() 
    content_object = GenericForeignKey('content_type', 'object_id') 

class Person(models.Model): 
    ... 

總之,我有:

RecordX ===GenericRelation===> PersonRecordMapping ===ForeignKey===> Person 

我的應用程序的顯示邏輯遵循這些關係來顯示映射到每個RecordX所有Person S:

views.py

@rendered_with('template.html') 
def show_all_recordXs(request): 
    recordXs = RecordX.objects.all() 
    return { 'recordXs': recordXs } 

這個問題是在模板:

模板.html

{% for recordX in recordXs %} 
    {# Display RecordX's other fields here #} 
    <ul> 
    {% for map in record.people_all %}{# <=== This generates a query every time! #} 
     <li>{{ map.person.name }}</li> 
    {% endfor %} 
    </ul> 
{% endfor %} 

如前所述,每當我請求與RecordX相關的Person時,它都會生成一個新的查詢。我似乎無法弄清楚如何最初預取這些以避免多餘的查詢。

如果我嘗試selected_related,則會出現錯誤,表示此處沒有selected_related字段(錯誤消息:Invalid field name(s) given in select_related: 'xxx'. Choices are: (none))。毫不奇怪,我現在看到 - 這款機型沒有任何FK。

如果我嘗試prefetch_related('people'),不會拋出任何錯誤,但我仍然可以像以前一樣在模板中的每個循環上獲得相同的重複查詢。同樣適用於prefetch_related('people__person')。如果我嘗試prefetch_related('personrecordmapping'),則會出現錯誤。

沿this answer行,我考慮過做嘗試通過類似模擬select_related

PersonRecordMapping.objects.filter(object_id__in=RecordX.objects.values_list('id', flat=True)) 

,但我不明白的_content_object_cache不夠好,這個答案適應我的情況(如果連正確的做法)。

所以 - 我怎麼能預先獲取所有Person年代到RecordX,以免發生ň查詢時,頁面上會顯示ňRecordX對象?

感謝您的幫助!

回答

0

確認,顯然我需要撥打 - prefetch_related('people', 'people__person')。嘆。