Résolue

Question à propos de la méthode __iter__

# Orienté objet # Notions théoriques # Django

Bonjour,


Dans le livre django 4 by exemple pour la gestion de panier il utilise django session. Pour ce faire il créer une class cart comme suit :


class Cart:    
    def __init__(self, request):
        """        Initialize the cart.        """        
        self.session = request.session
        cart = self.session.get(settings.CART_SESSION_ID)
        if not cart:
            # save an empty cart in the session
            cart = self.session[settings.CART_SESSION_ID] = {}
        self.cart = cart
    def __iter__(self):
        """        Iterate over the items in the cart and get the products        from the database.        """
        product_ids = self.cart.keys()
        # get the product objects and add them to the cart
        products = Product.objects.filter(id__in=product_ids)
        cart = self.cart.copy()
        for product in products:
            cart[str(product.id)]['product'] = product
        for item in cart.values():
            item['price'] = Decimal(item['price'])
            item['total_price'] = item['price'] * item['quantity']
            yield item

Je ne comprends pas du tout ce que fait la méthode __iter__. Je comprends que c'est un générateur mais j'ai toujours eu du mal jusqu'à présent pour comprendre l'intéret d'un générateur et dans ce cas précis je ne comprends pas qu'elle iintere cela apportte de surcharger la méthode __iter__ ?



Salut Flavien !


La méthode iter est appelée lorsque l'on itère sur l'objet Cart (ce qui arrive notamment quand tu utilises une boucle for).


Cette méthode retourne un générateur qui itère sur les éléments du panier (c'est-à-dire les items).


La raison pour laquelle on utilise un générateur plutôt qu'une liste (par exemple) pour stocker les items est que les générateurs sont des structures de données plus légères, qui ne prennent pas de place en mémoire tant qu'on ne les utilise pas.


Cela peut être intéressant si le panier contient beaucoup d'éléments.


En surchargeant la méthode iter, on peut également modifier le comportement de l'itération.


Par exemple, dans le cas présent, la méthode va chercher chaque produit correspondant à l'ID d'un item dans le panier, et ajouter ce produit à l'item.


Cela permet d'avoir toutes les informations nécessaires sur chaque item lorsqu'on itère sur le panier.

Si je comprends bien cette méthode va être appelé par exemple dans une vue pour afficher tous les éléments du panier c'est bien ça ? Et faire un peu plus de travaille que d'habitude ?


Et dans mon template je vais avoir quelque chose du genre :

{% for item in cart %}

Si je ne la modifie pas cette méthode, tout ce qu'elle fait c'est itérer sur la liste des items présent dans mon panier c'est bien ça ?

En effet, cette méthode serait appelée dans une vue pour afficher les éléments du panier.


Elle parcourt la liste d'items dans le panier et pour chaque item, elle crée un dictionnaire avec les informations nécessaires (ici le prix et le prix total mais tu pourrais avoir d'autres éléments, comme l'image, nom, prix, quantité etc).

Dans le template, tu aurais un code du type :


{% for item in cart %}
  <div>
    <img src="{{ item.image }}">
<h3>{{ item.name }}</h3>
<p>{{ item.total_price }}€</p>
<p>Quantité: {{ item.quantity }}</p>
</div>
{% endfor %}


Cela afficherait chaque élément du panier avec les informations correspondantes.

OK merci pour ton retour, c'est clair maintenant !

Inscris-toi

(c'est gratuit !)

Inscris-toi

Tu dois créer un compte pour participer aux discussions.

Créer un compte

Rechercher sur le site

Formulaire de contact

Inscris-toi à Docstring

Pour commencer ton apprentissage.

Tu as déjà un compte ? Connecte-toi.