• [^] # Re: Préciser "Simplification des QuerySetManager"

    Posté par (Mastodon) . En réponse à la dépêche Django 1.7, « le framework web pour les perfectionnistes sous pression ». Évalué à 4. Dernière modification le 06 mars 2015 à 15:57.

    Bonjour,

    Bon, je me coltine la description technique...

    Un Queryset est ce qui permet de décrire une requête dans l'ORM.

    Typiquement, ça ressemble à un truc comme ça :

    # dans models.py : 
    class Machin(models.Model):
     foo = models.IntegerField()
     bar = models.CharField(max_length=255)
     rel_1 = models.ForeignKey('app.FirstRelatedTable') # n::1
     rel_2 = models.Many2Many('app.SecondRelatedTable') # n::n
     rel_2 = models.One2One('app.ThirdRelatedTable') # 1::1
    qset = (models.Machin.objects
     .filter(foo__exact=1)
     .filter(bar__icontains='hello')
     .select_related()
     .prefetch_related('rel_2'))

    Depuis le modèle Machin (représenté par la table machin dans la base de données), je prends tout puis je sélectionne :

    • ceux qui ont le champ foo qui vaut 1 (WHERE foo = 1)
    • ceux qui ont le champ '''bar''' contiens la chaine 'hello', non sensible à la casse ( WHERE bar like '%hello%')
    • je charge l'ensemble des relations de premier niveau avec select_related() : les objets FirstRelatedTable et ThirdRelatedTable sont instanciés directement.
    • je charge les objets qui ont une relation M2M avec prefetch_related('rel_2')

    Il est important que comprendre avec django, c'est que les querysets sont fainétants : il ne font rien tant qu'on ne les parcourt pas explicitement.

    # dans le template
    <ul>
    {% for item in qset %}
     <li>{{ item.foo }} : {{ item.rel_1 }} / 
     {% for related in item.rel_2.all %} # Le 'all' permet le parcours du manager de la relation rel_2 
     {{ related }}
     {% endfor %}
     </li>
    {% endfor %}
    </ul>

    OK ?

    L'histoire des QuerysetManager, c'est pour 2 choses :

    • un QuerysetManager est créé implicitement par django :

      • Si on a un m2m, django créé le manager tout seul, et on peut récupérer les données depuis les 2 côtés de la relation
      • Si FK : en spécifiant un manager à la main dans la destimation de la FK, on a le même comportement : on peut récupérer des objets via la relation inverse.
    • On peut aussi définir des classes avec des méthodes ad hoc pour ne par réécrire encore et encore les même querysets, et c'est à ça que ça sert les querysets...

    J'espère que j'ai été clair...

    Bon week-end !