Django-fr

Forum

#1 21-06-2011 09:51:55

ioo
Membre
Inscription : 09-06-2011
Messages : 3

Optimisation de requêtes

Bonjour,

J'ai un objet Shirt qui a des relations oneToMany

class Shirt(models.Model):
    advisor = models.ForeignKey(Advisor, verbose_name=_('Advisor'))
    outer_fabric = models.ForeignKey(Fabric, blank=True, null=True, related_name='shirts_outer',
                                     verbose_name=_('Outer Fabric'))
    inner_fabric = models.ForeignKey(Fabric, blank=True, null=True, related_name='shirts_inner',
                                     verbose_name=_('Inner Fabric'))
    [...]

class Fabric(models.Model):
    """Tissu"""
    name = models.CharField(_('name'), max_length=255)
    reference = models.CharField(max_length=25, unique=True)

class Advisor(User):
    """ Advisor model class """

    class Meta:
        proxy = True
        verbose_name = _('Advisor')
        verbose_name_plural = _('Advisors')

class Profile(models.Model):
    """ Profile class is the same for all types of users """
    user = AutoOneToOneField(User)
    advisor = models.ForeignKey('advisors.Advisor', null=True, blank=True, default=None, related_name='advisor', verbose_name=_('Advisor'))

Le projet utilise les middleware django.contrib.sessions.middleware.SessionMiddleware, django.contrib.auth.middleware.AuthenticationMiddleware
L'objet Advisor est un proxy de l'objet profile et est lié par celui-ci à l'objet User de django.

Les autres clés sont vers un objet Fabric qui n'a pas de clés étrangères. Dans l'objet Shirt il existe encore des clés étrangères qui pointent vers des objets du même type que l'objet Fabric cad sans clés étrangères.

Lorsque je fais Shirt.objects.select_related().get(pk=1) la requête est

SELECT * FROM `products_shirt` INNER JOIN `auth_user` ON (`products_shirt`.`advisor_id` = `auth_user`.`id`) WHERE `products_shirt`.`id` = 1

J'ai lu que la solution est de mettre les relations voulues dans select_related('inner_fabric') et j'ai bien un left join mais je ne comprend pas le comportement.
Il y a t-il plus simple que d'écrire en dur les relations ?
Est-ce que je m'y prend mal ?

Merci

Hors ligne

#2 21-06-2011 09:58:33

Florian Strzelecki
Membre
Inscription : 11-08-2010
Messages : 40

Re : Optimisation de requêtes

Bonjour,

Si je regarde la doc sur select_related je peux lire ceci :

> Note that, by default, select_related() does not follow foreign keys that
have null=True.

Cela a probablement un lien avec ton modèle, où les ForeignKey sont définies
avec "blank=True" et "null=True".

Doc 1.3 :
https://docs.djangoproject.com/en/1.3/ref/models/querysets/#select-related
Doc 1.2 :
https://docs.djangoproject.com/en/1.2/ref/models/querysets/#select-related
(Il me semble que ça ne change rien pour le select_related entre la 1.2 et
la 1.3, mais je n'ai pas lu dans le détail).

Le 21 juin 2011 10:51, Lionel Chanson <lionel _AT_ soreia.com> a écrit :

> Bonjour,
>
> J'ai un objet Shirt qui a des relations oneToMany
>
>

> class Shirt(models.Model):
>    advisor = models.ForeignKey(Advisor, verbose_name=_('Advisor'))
>    outer_fabric = models.ForeignKey(Fabric, blank=True, null=True,
> related_name='shirts_outer',
>                                     verbose_name=_('Outer Fabric'))
>    inner_fabric = models.ForeignKey(Fabric, blank=True, null=True,
> related_name='shirts_inner',
>                                     verbose_name=_('Inner Fabric'))
>    [...]
>
> class Fabric(models.Model):
>    """Tissu"""
>    name = models.CharField(_('name'), max_length=255)
>    reference = models.CharField(max_length=25, unique=True)
>
> class Advisor(User):
>    """ Advisor model class """
>
>    class Meta:
>        proxy = True
>        verbose_name = _('Advisor')
>        verbose_name_plural = _('Advisors')
>
> class Profile(models.Model):
>    """ Profile class is the same for all types of users """
>    user = AutoOneToOneField(User)
>    advisor = models.ForeignKey('advisors.Advisor', null=True, blank=True,
> default=None, related_name='advisor', verbose_name=_('Advisor'))
>
>

> Le projet utilise les middleware
> django.contrib.sessions.middleware.SessionMiddleware,
> django.contrib.auth.middleware.AuthenticationMiddleware
> L'objet Advisor est un proxy de l'objet profile et est lié par celui-ci
> à l'objet User de django.
>
> Les autres clés sont vers un objet Fabric qui n'a pas de clés
> étrangères. Dans l'objet Shirt il existe encore des clés étrangères
> qui pointent vers des objets du même type que l'objet Fabric cad sans
> clés étrangères.
>
> Lorsque je fais Shirt.objects.select_related().get(pk=1) la requête est
> [quote]
> SELECT * FROM `products_shirt` INNER JOIN `auth_user` ON
> (`products_shirt`.`advisor_id` = `auth_user`.`id`) WHERE
> `products_shirt`.`id` = 1
> [/quote]
>
> J'ai lu que la solution est de mettre les relations voulues dans
> select_related('inner_fabric') et j'ai bien un left join mais je ne
> comprend pas le comportement.
> Il y a t-il plus simple que d'écrire en dur les relations ?
> Est-ce que je m'y prend mal ?
>
> Merci
> _______________________________________________
> django mailing list
> django _AT_ lists.afpy.org
> http://lists.afpy.org/mailman/listinfo/django
>

Hors ligne

#3 21-06-2011 10:30:47

ioo
Membre
Inscription : 09-06-2011
Messages : 3

Re : Optimisation de requêtes

Merci de ta réponse et désolé que ce soit sur le fait que j'ai mal lu la doc hmm

Hors ligne

#4 21-06-2011 10:47:04

Florian Strzelecki
Membre
Inscription : 11-08-2010
Messages : 40

Re : Optimisation de requêtes

Pas de soucis va, c'est une petite ligne coincée entre deux encadrées.
J'ai eu une intuition parce qu'il me semble avoir déjà rencontré un problème
similaire. ;-)

Le 21 juin 2011 11:30, Lionel Chanson <lionel _AT_ soreia.com> a écrit :

> Merci de ta réponse et désolé que ce soit sur le fait que j'ai mal lu la
> doc hmm
> _______________________________________________
> django mailing list
> django _AT_ lists.afpy.org
> http://lists.afpy.org/mailman/listinfo/django
>

Hors ligne

Pied de page des forums