2017-02-03 1 views
0

Je sais qu'il y a déjà un question similaire, mais je pense que mon cas est un peu plus compliqué car j'ai un point d'entrée différent.Django: prefetch_related() avec m2m par rapport v2

Ce sont mes modèles:

class m_Interaction(models.Model): 
    fk_ip = models.ForeignKey('m_IP', related_name="interactions") 

class m_User(models.Model): 
    name = models.CharField(max_length=200) 

class m_IP(models.Model): 
    fk_user = models.ForeignKey('m_User', related_name="ips") 

class m_Feature(models.Model): 
    name = models.CharField(max_length=200) 
    m2m_interaction = models.ManyToManyField(m_Interaction, related_name='features', through='m_Featurescore') 

class m_Featurescore(models.Model): 
    score = models.FloatField(null=False) 
    fk_interaction = models.ForeignKey(m_Interaction, related_name='featurescore') 
    fk_feature = models.ForeignKey(m_Feature, related_name='featurescore') 

Je commence par m_User, suivre la relation inverse sur m_IP aux interactions (m_Interaction). Ensuite, je veux obtenir chaque m_Featurescore.score pour chaque interaction pour une instance spécifique de m_Feature.

Ma requête de travail pour accéder au moins toutes les interactions d'une manière performante:

m_User.objects.all().prefetch_related('ips__interactions') 

Mais je ne peux pas le bon « prefetch_related'-déclaration pour accéder au m_Featurescore.score comme celui-ci

db_obj_interaction.featurescore.get(fk_feature=db_obj_feature).score 

sans faire beaucoup de requêtes.

J'ai déjà essayé presque toutes les combinaisons des éléments suivants:

'ips__interactions__features__featurescore' 

Toutes les suggestions?

+1

Que diriez-vous « ips__interactions__featurescore »? En outre, l'utilisation de la méthode get() signifie que vous forcez l'ORM à faire une requête. Vous devez utiliser la méthode all() afin de profiter de la prélecture. Si vous avez besoin de filtrage, utilisez un objet Prefetch(). – noamk

+0

@noamk parfait. Merci! –

Répondre

0

J'ai trouvé la réponse à ma propre question avec l'aide de noamk dans les commentaires:

Je ne considère pas que le get() - méthode db_obj_interaction.featurescore.get(fk_feature=db_obj_feature).score émettra un nouveau chaque fois que la requête, il est appelé (c'est un peu évident maintenant). Par conséquent, j'ai simplement restructuré mon code et maintenant je n'ai plus besoin de get() et je peux utiliser l'avantage de la prefetch.

Si quelqu'un a encore besoin de filtrer l'Prefetch()-object doit être utilisé comme suggéré par noamk