2017-02-17 1 views
1

J'ai créé une instruction avec l'API queryset de Django qui me donne des moyennes hebdomadaires pour certaines données de ma base de données.Annotation des valeurs hebdomadaires

Les données renvoyées sont dans ce format: (6, 4,0), (9, 5.0) ... etc où la première valeur dans chaque tuple représente le numéro de la semaine et la deuxième valeur représente une moyenne de Les données.

Cependant, les semaines ne sont pas séquentielles et ne sont incluses que s'il existe des données pour cette semaine. Remarquez comment la première semaine est 6 et la deuxième semaine est 9. Je voudrais obtenir les semaines 6, 7, 8, 9 au lieu de seulement retourner les semaines pour lesquelles des données existent. Est-ce possible à l'aide de jeux de requêtes et d'annotations Django?

data = post_queryset.annotate(week=WeekFunc('post__start_time')) \ 
        .values_list('week') \ 
        .annotate(sum=Sum('goods')) \ 
        .order_by('week') 

Semaine est une extension de la Func classe

class WeekFunc(Func): 
    def as_mysql(self, compiler, connection): 
     self.function = 'WEEK' 
     return super(WeekFunc, self).as_sql(compiler, connection) 

post_queryset est un queryset qui est passé à cette fonction

+1

Ajoutez le code que vous avez actuellement, y compris la partie du modèle qui est pertinente. (Utilisez "Modifier", ne le publiez pas dans un commentaire.) – Risadinha

+0

Fait! Merci... – zubhav

Répondre

1

Vous avez pas encore posté votre Django Modèle, alors voici une réponse théorique:

Pour afficher des lignes de données où votre table de base n'a aucune entrée, vous devez aligner (: = joindre) les données avec un autre ensemble de données contenant des entrées pour chaque ligne résultante.

Exemple:

Votre table modèle contient des entrées horodatées pour:

  • la semaine 6
  • semaines 9

Si vous souhaitez obtenir des données pour toutes les semaines, vous devez rejoignez-le contre un jeu de données qui contient des horodatages pour tous semaines. Comment vous créez ce type de jeu de données, je ne peux pas vous le dire. Je suppose qu'il pourrait y avoir une fonction ou une instruction select dans MySQL qui peut le faire.

toutes les semaines se sont joints pour modéliser des données:

- week 1 == <no data> => week 1: sum=0 
- week 2 == <no data> => week 2: sum=0 
- week 3 == <no data> => week 3: sum=0 
- week 4 == <no data> => week 4: sum=0 
- week 5 == <no data> => week 5: sum=0 
- week 6 == 4 goods => week 6: sum=4 
- week 7 == <no data> => week 7: sum=0 
- week 8 == <no data> => week 8: sum=0 
- week 9 == 5 goods => week 9: sum=5 

Une fois que vous savez comment créer cette liste des semaines, vous pouvez le joindre par rapport aux données du modèle et la jointure en combinaison avec la fonction SUM() devrait alors générer des entrées avec 0 valeur pour toutes les semaines où vous n'avez pas de données.

Cela peut valoir la peine de s'asseoir et de simplement essayer d'y parvenir en pur SQL afin de comprendre ce qui doit se passer sur cette couche. Alors seulement, pouvez-vous aller de l'avant et créer une solution dans la couche ORMO de Django - soit en fournissant simplement du SQL brut ou en essayant d'utiliser la fonction annotate et extra pour recréer la solution SQL pure.