2011-01-04 2 views
2

J'ai un 'éléments' dans le jeu de requête contenant des instances de l'élément de modèle. Les éléments ont une « série » clé étrangère, et chaque série a des champs:Liste de dictionnaires à partir de valeurs uniques sur plusieurs champs dans Django

subtopic_1_name 
subtopic_1_slug 
subtopic_2_name 
subtopic_2_slug 
subtopic_3_name 
subtopic_3_slug 

J'ai besoin de générer un « aplaties » liste des dicts de la forme

[{'name': 'somename', 'slug': 'someslug'}, {'name': 'anothername' 'slug': 'anotherslug'}, ... ] 

où slug « name » et » 'correspondent aux valeurs uniques des trois champs name et slug, à l'exclusion de la chaîne vide. J'utilise actuellement une boucle for inefficace avec 'not in' pour vérifier l'unicité. Cela fonctionne mais est trop lent car les 'éléments' peuvent avoir jusqu'à 1,9 million de membres.

Qu'est-ce qu'un moyen efficace de faire cela?

Mise à jour:

Voici le meilleur que j'ai jusqu'à présent, mais il doit y avoir un moyen plus rapide:

subtopic_list = [] 
ones = elements.values_list('series__subtopic1_name', 'series__subtopic1_slug').distinct() 
twos = elements.values_list('series__subtopic2_name', 'series__subtopic2_slug').distinct() 
threes = elements.values_list('series__subtopic3_name', 'series__subtopic3_slug').distinct() 
for num in [ones, twos, threes]: 
    for name, slug in num: 
     if name != '': 
      subtopic_list.append({'name': name, 'slug': slug)} 

Répondre

0

Qu'en est-il filtrer les noms vides dans la requête db en utilisant 'exclure?

ones = elements.exclude('series__subtopic1_name'='').\ 
    values_list('series__subtopic1_name','series__subtopic1_slug').distinct() 

twos = elements.exclude('series__subtopic2_name'='').\ 
    values_list('series__subtopic2_name', 'series__subtopic2_slug').distinct() 

threes = elements.exclude('series__subtopic3_name'='').\ 
    values_list('series__subtopic3_name', 'series__subtopic3_slug').distinct() 

# concatenate element of twos and threes into list 'ones' 
ones.extend(twos) 
ones.extend(threes) 

# we already filtered empty names in the db query, 
# so we can just return the subtopic_list 
subtopic_list = [{'name': name, 'slug': slug} for name, slug in ones] 
+0

Merci. J'espérais un moyen d'éviter le besoin pour les trois appels distincts(), mais c'est un code plus propre. – thebenedict

+0

Pourquoi voulez-vous vous débarrasser des appels distincts()? C'est possible, mais dans votre question vous avez mentionné que vous vouliez éliminer la boucle coûteuse. – Tommy

Questions connexes