0

Mon sérialiseur est constitué d'une agrégation d'un champ imbriqué et je calcule une moyenne d'un nombre sur ces objets imbriqués.Comment filtrer un fichier imbriqué en moyenne sur Django Rest Framework?

L'objet Question est imbriqué avec un objet Difficulty_Question (une relation 'ForeignKey' sur l'objet Difficulty_Question). Difficulty_Question avoir un champ de 'difficulté' que j'ai moyenné et agrégé sur l'objet Question. (Voir get_difficulty fonction)

Je souhaite filtrer l'objet Question avec une gamme de difficulté.

Mon sérialiseur ressemble:

serializer.py:

class QuestionListSerializer(ModelSerializer): 

    difficulty = serializers.SerializerMethodField() 

    def get_difficulty(self, obj): 
     average = obj.difficulty_questions.all().aggregate(Avg('difficulty')).get('difficulty__avg') 
     if average is None: 
      return 0 
     return average 

    class Meta: 
     model = models.Question 
     fields = (
      'id', 
      'name', 
      'difficulty', 
     ) 

J'essaie de filtrer cet objet django par la difficulté, mais tout ce que je peux faire est de filtrer tous les objets du champ imbriqué , pas la moyenne de tous les objets ..

view.py

class QuestionFilter(FilterSet): 
    difficulty_questions__difficulty__gt = django_filters.NumberFilter(name='difficulty_questions__difficulty', lookup_expr='gt') 
    difficulty_questions__difficulty__lt = django_filters.NumberFilter(name='difficulty_questions__difficulty', lookup_expr='lt') 

    class Meta: 
     model = models.Question 
     fields = {'difficulty_questions__difficulty': ['lt', 'gt']} 

class QuestionViewSet(ModelViewSet): 
    queryset = models.Question.objects.all() 

    serializer_class = serializers.QuestionSerializer 

    action_serializers = { 
     'retrieve': serializers.QuestionSerializer, 
     'list': serializers.QuestionListSerializer, 
     'create': serializers.QuestionSerializer 
    } 

    filter_class = QuestionFilter 

    def get_serializer_class(self): 

     if hasattr(self, 'action_serializers'): 
      if self.action in self.action_serializers: 
       return self.action_serializers[self.action] 

     return super(QuestionViewSet, self).get_serializer_class() 

J'utilise aussi différentes serializers pour les vues de détail et la liste ...

Toute idée de comment je pourrais filtrer mon objet « Question » en moyenne du champ « difficulté »?

Répondre

0

Essayez:

class QuestionListSerializer(ModelSerializer): 

    difficulty_avg = serializers.IntegerField() 

vue

class QuestionFilter(FilterSet): 
    difficulty_avg__gt = django_filters.NumberFilter(name='difficulty_avg', lookup_expr='gt') 
    difficulty_avg__lt = django_filters.NumberFilter(name='difficulty_avg', lookup_expr='lt') 

    class Meta: 
     model = models.Question 
     fields = {'difficulty_avg': ['lt', 'gt']} 


class QuestionViewSet(ModelViewSet): 
    queryset = models.Question.objects.annotate(difficulty_avg=Avg('difficulty_questions__difficulty')) 
+0

C'est parfait, merci! – Jibsgrl