2017-01-17 3 views
0

ein GenericRelation Mit Record s Person s auf der Karte, ich habe den folgenden Code, der richtig funktioniert, aber es ist ein Performance-Problem, das ich ansprechen versuche:Django Query-Caching durch eine ForeignKey auf einem 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): 
    ... 

Zusammengefasst habe ich:

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

Die Anzeigelogik in meiner Anwendung folgt diese Beziehungen alle Person s auf jeden RecordX abgebildet anzuzeigen:

views.py

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

Das Problem kommt in der Vorlage:

Vorlage .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 %} 

Wie angegeben, jedes Mal, wenn ich die Person s im Zusammenhang mit der RecordX anfordern, generiert es eine neue Abfrage. Ich kann anscheinend nicht herausfinden, wie diese im Voraus abgerufen werden, um die redundanten Abfragen zu vermeiden. Wenn ich selected_related versuche, bekomme ich einen Fehler, dass keine selected_related Felder hier möglich sind (Fehlermeldung: Invalid field name(s) given in select_related: 'xxx'. Choices are: (none)). Nicht überraschend, ich sehe jetzt - es gibt keine FKs auf diesem Modell.

Wenn ich prefetch_related('people') versuche, wird kein Fehler ausgelöst, aber ich bekomme immer noch dieselben wiederholten Abfragen auf jeder Schleife in der Vorlage wie zuvor. Ebenso für prefetch_related('people__person'). Wenn ich prefetch_related('personrecordmapping') versuche, erhalte ich einen Fehler.

Nach dem Vorbild der this answer hielt ich versuche dabei ein select_related über so etwas wie zu simulieren:

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

aber ich verstehe nicht die _content_object_cache gut genug, um diese Antwort auf meine Situation anzupassen (auch wenn die richtiger Ansatz). So

- wie kann ich Pre-Fetch all Person s zu dem RecordX s n Abfragen zu vermeiden, wenn die Seite nRecordX Objekte angezeigt werden?

Danke für Ihre Hilfe!

Antwort

0

Ack, anscheinend musste ich anrufen beide - prefetch_related('people', 'people__person'). SEUFZER.

Verwandte Themen