django вложенный сериализатор и набор представлений

#django #django-models #django-rest-framework #django-serializer

#django #django-модели #django-rest-framework #django-сериализатор

Вопрос:

У меня проблема с вложенным сериализатором и набором представлений

Мои модели похожи на это, и их отношения довольно ясны

Этот класс имеет вложенные отношения друг с другом

 class Sim(models.Model):
   name = models.CharField(max_length=255)
   subject = models.ManyToManyField(Subject)
   grade = models.ManyToManyField(Grade)

class Exercise(models.Model):
   name = models.CharField(max_length=255)
   sim = models.OneToOneField(Sim,related_name='sims', on_delete=models.CASCADE)

class Result(models.Model):
   is_example = models.BooleanField(null=False)
   exercise = models.ForeignKey(Exercise, on_delete=models.CASCADE, blank=True, null=True, 
       default=None)
class Parameter(models.Model):
    name = models.CharField(max_length=255)
    exercise = models.ForeignKey(Exercise, on_delete=models.CASCADE, blank=True, null=True, 
        default=None)

class ExerciseData(models.Model):
    value = models.CharField(max_length=255)
    parameter = models.ForeignKey(Parameter, on_delete=models.CASCADE, blank=True, 
        null=True, default=None)
    result = models.ForeignKey(Result, on_delete=models.CASCADE, blank=True, null=True, 
        default=None)
    
 

Я хочу создать ExerciseSerializer следующим образом

 class ExerciseSerializer(serializers.ModelSerializer):
    parameters = ParameterSerializer(many=True, read_only=True)
    exercisedatas = ExerciseDataSerializer(many=True, read_only=True)
    sims = SimSerializer(many=True, read_only=True)

    class Meta:
       model = models.Exercise
       fields = ['name', 'id', 'parameters', 'exercisedatas','sims']

    extra_kwargs = {
        'id': {'read_only': True},
    }

class SimSerializer(serializers.ModelSerializer):
    grade = GradeSerializer(many=True, read_only=True)
    subject = SubjectSerializer(many=True, read_only=True)

    class Meta:
        model = models.Sim
        fields = ['name', 'subject', 'grade', 'id']

    extra_kwargs = {
        'id': {'read_only': True},
    }

class ParameterSerializer(serializers.ModelSerializer):
    class Meta:
        model = Parameter
        fields = ['name', 'id']

    extra_kwargs = {
        'id': {'read_only': True},
    }

class ResultSerializer(serializers.ModelSerializer):
    class Meta:
        model = Result
        fields = ['is_example', 'id']

    extra_kwargs = {
        'id': {'read_only': True},
    }

class ExerciseDataSerializer(serializers.ModelSerializer):
    parameter_set = ParameterSerializer(many=True, read_only=True)
    result_set = ResultSerializer(many=True, read_only=True)

    class Meta:
       model = ExerciseData
       fields = ['value', 'id', 'parameter_set', 'result_set']

    extra_kwargs = {
        'id': {'read_only': True},
    }
 

И мои viewsets создаются как :

 class ExerciseViewset(viewsets.ModelViewSet):
    serializer_class = serializers.ExerciseSerializer
    pagination_class = StandardResultsSetPagination
    queryset = models.Exercise.objects.all()

    def filter_queryset(self, queryset):
        queryset = self.get_queryset()
        queryset = play_filtering_form(queryset, self.request.query_params)
        return queryset
 

Я не получаю желаемый результат

Вывод

 {
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "name": "تمرین",
            "id": 1
        }
]
 

}

Я не получаю три элемента параметров и exercisedatas и sims

Комментарии:

1. Я не очень понял ваш вопрос, вы пытаетесь выполнить все упражнения?

2. @Omar да, я пытаюсь выполнить все упражнения

Ответ №1:

Я не проверял ваши модели и код сериализаторов, предполагая, что они верны, но в вашем наборе представлений вы могли бы использовать более простой способ, используя общие представления.

Попробуйте следующий класс представления:

 class ExerciseViewset(generics.ListAPIView):
    # form its name, ListAPIView do one action which is GET for list of results
    serializer_class = serializers.ExerciseSerializer
    pagination_class = StandardResultsSetPagination
    queryset = models.Exercise.objects.all()
 

Если вы хотите настроить результат своего запроса, вы можете переопределить метод get_queryset следующим образом:

 def get_queryset(self):
    # you can use self.queryset or models.Exercise.objects.filter(any filter)
    return self.queryset.filter(some filtering)
 

Краткое изложение общих представлений:

общие сведения.ListAPIView: позволяет использовать GET только для перечисления многих результатов

общие сведения.RetrieveAPIView: разрешает только GET, используется для получения определенного результата с помощью lookup_field, по умолчанию: pk (например, в вашем urls.py : упражнение/<int:pk>/)

общие сведения.CreateAPIView: разрешает только POST

общие сведения.UpdateAPIView: разрешает только вставлять / исправлять

общие сведения.DestroyAPIView: разрешает только УДАЛЕНИЕ

Существуют отличные комбинации, такие как: дженерики.ListCreateAPIView (POST, GET), дженерики.Извлекать обновления из просмотра (ПОЛУЧИТЬ, ПОМЕСТИТЬ / ИСПРАВИТЬ)…

Ссылка на документацию: общие представления DRF