Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

Django : Sérialiser le résultat d'un Queryset construit avec prefetch_related

+1 vote

Modèles:

class Agent(models.Model):
    ...
class AgentAddress(models.Model):
   agent = models.ForeignKey(Agent)
   ...

Vue:

class AgentDetailModal(LoginRequiredMixin, DetailView):
template_name = 'agent/agent_detail_modal.html'
model = Agent


def render_to_response(self, context, **response_kwargs):
    agent = Agent.objects.prefetch_related('agentaddress_set').filter(pk=self.kwargs['pk'])
    print agent
    agent_serialized = serializers.serialize('json', agent)
    print agent_serialized
    from django.db import connection
    print connection.queries
    return JsonResponse(agent_serialized, safe=False)

Le "print connection.queries" me renvoi bien deux requêtes dont une qui tape dans la table AgentAddress. Le "print agent" me renvoi bel object

[<Agent: Firstname Lastname>]

mais le "print agent_serialized" me renvoi un beau dictionnaire SANS aucune référence à ma chère table "AgentAddress".
(Je fais bien sûr le test avec un agent qui a une pk avec une entrée dans la table "AgentAddress").

Est-ce que le merge python fait par prefetch_related ne serait pas en cause ? Lié au fait que "print agent.query" ne renvoi qu'une seule requête ?

Je voudrais renvoyer tout ce que concerne un Agent et qui est stocké dans qques tables liées comme "AgentAdress"

( Et hors titre, je suis étonné que la DetailView ne filtre pas automatiquement par pk et que je doive rajouter un "filter".)

demandé 25-Jan-2015 par Youpsla (120 points)
edité 25-Jan-2015 par Youpsla

1 Réponse

+3 votes
 
Meilleure réponse

Je voudrais renvoyer tout ce que concerne un Agent et qui est stocké dans qques tables liées comme AgentAddress"

a = Agent.objects.select_related('agentaddress').get(pk=5)
ad = a.agentaddress_set.all() # aucune requete sur la db

Dans ce cas, il s'agit d'un simple foreign key, donc un select related fait l'affaire.

répondu 25-Jan-2015 par Nsukami_ (1,998 points)
sélectionné 26-Jan-2015 par Youpsla

Merci beaucoup. Cela fonctionne à merveille. J'ai trouvé une solution fonctionnelle (en 1.7) en faisant:

agent = Agent.objects.filter(pk=self.kwargs['pk']).prefetch_related(
            Prefetch('agentaddress_set', to_attr="dede"),
            Prefetch('agentvarious_set', to_attr="dodo"))

Pas encore tout compris à ce qui se passe en interne mais vais regarder.

Tu précise qu'il s'agit d'une FK donc selectrelated est OK. Cela sous-entend que prefetchrelated s'utilisera en m2m ?

@Youpsla grosso merdo, oui, prefetch related pour les relations de type m2m. Je te colle vite fait ce qu'il faut retenir: "prefetch_related, on the other hand, does a separate lookup for each relationship, and does the ‘joining’ in Python. This allows it to prefetch many-to-many and many-to-one objects, which cannot be done using select_related, in addition to the foreign key and one-to-one relationships that are supported by select_related". Ça fait plaisir de parler français :)

...