3

I made an APIView of a django function

Views.py

class TakenQuizListViewAPI(APIView):

    def get(self, request, *args, **kwargs):
        queryset = self.request.user.supplier.taken_quizzes.select_related('quiz', 'quiz__truck_type').order_by(
            'quiz__posted_on')

        query = suppliertakenquizSerializer(queryset, many=True).data

        return Response(query)

and it returns data like this:

    {
        "id": 5,
        "score": 0.0,
        "date": "2019-08-20T13:31:15.156691",
        "least_bid": 99,
        "confirmed": "Not Confirmed",
        "supplier": 32,
        "quiz": 16
    },

How can I get all the details of the quiz in the API ??

Expected Output:

{
    "id": 5,
    "score": 0.0,
    "date": "2019-08-20T13:31:15.156691",
    "least_bid": 99,
    "confirmed": "Not Confirmed",
    "supplier": 32,
    "quiz": { "foo": "",
              "bar": ""
             }
},

serializer:

class suppliertakenquizSerializer(serializers.ModelSerializer):

  class Meta:
    model = TakenQuiz
    fields = "__all__"

Model.py:

class TakenQuiz(models.Model):
    supplier = models.ForeignKey(Supplier, on_delete=models.CASCADE, related_name='taken_quizzes')
    quiz = models.ForeignKey(Quiz, on_delete=models.CASCADE, related_name='taken_quizzes')
    score = models.FloatField()
    date = models.DateTimeField(auto_now_add=True)
    least_bid = models.IntegerField(default=0)
    confirmed = models.CharField(max_length=100, default='Not Confirmed')

UPDATE What I tried:

I updated the serializer as such that when it gets the quiz ID it should return the quiz data but I am not sure if this is the right thing

class suppliertakenquizSerializer(serializers.ModelSerializer):
    quiz = serializers.SerializerMethodField()

    def get_items(self, obj):
        try:
            serializer = createrfqSerializer(Quiz.objects.get(pk=int(obj.)))
            quiz_data = serializer.data
        except ItemBatch.DoesNotExist:
            pass
        return quiz_data


    class Meta:
        model = TakenQuiz
        fields = "__all__"

4 Answers 4

2

We have depth parameter in the serializer meta class. we can make use of it like below. depth=1 will retrive all fields of a relation.

class suppliertakenquizSerializer(serializers.ModelSerializer):

  class Meta:
    model = TakenQuiz
    fields = "__all__"
    depth = 1

Referece: https://www.django-rest-framework.org/api-guide/serializers/#specifying-nested-serialization

Sign up to request clarification or add additional context in comments.

Comments

0

I created a function in my serializer to do it.

class suppliertakenquizSerializer(serializers.ModelSerializer):

    quiz = serializers.SerializerMethodField()

    def get_quiz(self, obj):
        try:
            serializer = createrfqSerializer(Quiz.objects.get(pk=obj.quiz.id))
            quiz_data = serializer.data
        except ItemBatch.DoesNotExist:
            pass
        return quiz_data


    class Meta:
        model = TakenQuiz
        fields = "__all__"

Comments

0

I think you should not need to drop to SerializerMethodField. That type of field is used when what you are trying to do is not possible to do in any other way. When I've seen it on code was usually a bad practice.

I think what you need is explained here 1 on the section "Nested Relationships". Basically on the field declaration you point to another serializer which will serialize that field. This allows you to define what you want in a declarative way. As you can see there are many more types of fields to do many things. DRF documentation is amazing!

2 Comments

I did it with SerializerMethodField only. Check the answer please and suggest if any change is required
Like I said on the answer, SerializerMethodField is used to provide a callback so you implement by hand something not supported by the framework. What you want to do is pretty standard and supported through nested serializers, so that's my suggestion.
0

Can you try the below serializer Class. You have to create a Serializer class for Quiz data and use the same in Serializermethod field.

Try this.

class suppliertakenquizSerializer(serializers.ModelSerializer):
      quiz = serializers.SerializerMethodField()

      def get_quiz(self, obj):
         try:
            serializer = QuizSerializer(Quiz.objects.get(pk=int(obj.)))
            quiz_data = serializer.data
          except quiz_data.DoesNotExist:
             pass
          return quiz_data

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.