Modèles, accès aux champs de la classe intermédiaire

Le problème exposé dans ce sujet a été résolu.

Bonjour à tous,

Débutant sur Django, j'aimerais savoir quelles sont les options pour accéder aux champs d'une classe intermédiaire. Partons du code du tuto:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
class Produit(models.Model):
    nom = models.CharField(max_length=30)

    def __unicode__(self):
        return self.nom

class Vendeur(models.Model):
    nom = models.CharField(max_length=30)
    produits = models.ManyToManyField(Produit, through='Offre')

    def __unicode__(self):
        return self.nom

class Offre(models.Model):
    prix = models.IntegerField()
    produit = models.ForeignKey(Produit)
    vendeur = models.ForeignKey(Vendeur)

    def __unicode__(self):
        return "{0} vendu par {1}".format(self.produit, self.vendeur)

Dans le tuto, il est dit que l'accès aux valeurs de la classe intermédiare est disponible via :

1
Offre.objects.get(vendeur=vendeur, produit=p1).prix

La-dessus pas de problème. Dans ma situation, je veux afficher tous les produits d'un vendeur, et donc aussi les offres propres à son vendeur. Est-il possible d'accéder à l'ensemble des produits directement avec les offres associées ? Par exemple pouvoir faire produit.offre.prix ?

Merci pour votre aide, jespère avoir été clair sur mon problème :)

Hey !

Pour commencer, j'ai du me raffraichîr un peu la mémoire sur le fonctionnement des relations N - N avec l'ORM de Django, et je pense que cette section de la documentation pourrait t'éclairer davantage sur ton problème : Django 1.10 - Extra fields on Many To Many relationships

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# Tout d'abord, voici deux instances que nous allons utiliser pour faire des requêtes.
mario = Vendeur.objects.create(nom='Mario')
mushroom = Produit.objects.create(nom='Mushroom')

# Comme tu as définis une table intermédiaire "Offre", il faut que tu utilises cette table
# pour créer une nouvelle entrée dans la base de données.
Offre.objects.create(vendeur=mario, produit=mushroom, prix=42)

# Pour avoir accès à tous les produits d'un vendeur, il faut utiliser l'attribut "produits"
mario.produits.all()
mario.produits.filter(name='Mushroom')

# Inversement, pour accéder à tous les vendeurs d'un produit, il faut utiliser
# l'attribut par défaut "vendeur_set"
mushroom.vendeur_set.all()
mushroom.vendeur_set.filter(name='Mario')

# Si tu trouves l'attribut "vendeur_set" peu explicite, tu peux spécifier un autre nom
# au niveau du modèle qui définit la relation N - N, avec le paramètre "related_name".
class Vendeur(models.Model):
    nom = models.CharField(max_length=30)
    produits = models.ManyToManyField(Produit, related_name='vendeurs', through='Offre')

# Ainsi, tu peux écrire tout simplement
mushroom.vendeurs.all()

# Sinon, pour obtenir toutes les offres d'un vendeur, ou toutes les offres d'un produit
# tu peux effectuer ta requête depuis le Manager de ton modèle "Offre".
Offre.objects.filter(vendeur=mario)
Offre.objects.filter(produit=mushroom)

# Tu peux également utiliser les RelatedManager des modèles "Produit" et "Vendeur"
mario.offre_set.all()
mario.offre_set.filter(prix=42)

mushroom.offre_set.all()
mushroom.offre_set.filter(prix=42)
+1 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte