Vous n'êtes pas identifié(e).
Bonjour,
je débute avec django et après avoir passé pas mal de temps à trouver une solution et à lire de la doc, je viens demander un coup de pousse à plus aguerri que moi...
Mon problème concerne la récupération de données avec le modèle que je possède et l'optimisation des traitements.
Mon problème :
J'ai une liste d'identifiants (specific_id) et je dois récupérer les produits correspondants (dans le même ordre) et charger toutes les données relatives aux répertoires, plateformes et capteurs.
Dans le but d'afficher cela.
Mon modèle :
class Product(models.Model):
specific_id = models.CharField(max_length=100, unique=True, blank=False, null=False)
shortname = models.CharField(max_length=100, unique=False, blank=True, null=False)
class Repository(models.Model):
product = models.ForeignKey(Product, blank=True, null=True)
name = models.CharField(max_length=200, unique=True, blank=False, null=False)
url = models.CharField(max_length=2048, blank=True, null=True)
class SourceContribToProduct(models.Model):
source = models.ForeignKey(Source)
product = models.ForeignKey(Product)
class Source(models.Model):
products = models.ManyToManyField(Product, through='SourceContribToProduct')
shortname = models.CharField(max_length=100, unique=True, blank=False, null=False)
platform = models.ForeignKey(Platform, blank=True, null=True)
sensor = models.ForeignKey(Sensor, blank=True, null=True)
class Sensor(models.Model):
shortname = models.CharField(max_length=50, unique=True, blank=False, null=False)
type = models.TextField(blank=True, null=True)
class Platform(models.Model):
shortname = models.CharField(max_length=50, unique=True, blank=False, null=False)
description = models.TextField(blank=True, null=True)
Ma solution :
ids = [1, 2, 3, 'AZT_TY', 'SGT_YY']
# Retrive list of objects
products = Product.objects.filter(specific_id__in=ids).prefetch_related('repository_set', 'source_set')
for p in products:
p.repositories = p.repository_set.all()
p.sources = Source.objects.filter(sourcecontribtoproduct__product_id=p.id).select_related('sensor_set', 'platform_set')
for s in p.sources:
s.sensor
s.platform
# Sort the list
products = list(products)
products.sort(key=lambda t: ids.index(t.specific_id))
Mes questions :
Voilà ce que j'ai fait, mais je trouve cela lent.
Que pensez-vous de ce code ? Comment pourrais-je l'optimiser ?
Je n'ai que 194 objets (pas plus de 5 repertoires par objet et pas plus de 3 sources par objets) et cela me prend presque 5 secondes !
Existe-t-il un moyen simple de dire de charger tous les éléments des sets sur plusieurs niveau ?
Merci d'avoir pris le temps de me lire
Bonne journée
Hors ligne
A priori, tu pourrais charger toutes tes sources en utilisant un __in = ids dans le filter et donc éviter de boucler sur les produits.
Hors ligne
J'ai trouvé la réponse à ma question, je n'ai pas besoin d'itérer sur les objets pour les charger dans view.py. Simplement besoin de créer une querySet et d'accéder dans ma template aux éléments chargés dans les _set. Dans view.py :
`products=Product.objects.filter(specific_id__in=ids).prefetch_related('repository_set', 'source_set').select_related('repository_set', 'source_set')`
Dans ma template, itérer sur :
{% for src in product.source_set.all %}
{{src.platform.shortname}} / {{src.sensor.shortname}}<br/>
{% endfor %}
{% for repo in product.repository_set.all %}
{{repo.url}}
{% endfor %}
Et c'est tout...
Hors ligne
A priori, tu pourrais charger toutes tes sources en utilisant un __in = ids dans le filter et donc éviter de boucler sur les produits.
Merci pour ton indication Xavier
Hors ligne