Yantra Logistics
Yantra Logistics

Reputation: 308

Retrieve data in API based on ID in Django Rest Framework

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__"

Upvotes: 3

Views: 6205

Answers (4)

anjaneyulubatta505
anjaneyulubatta505

Reputation: 11685

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

Upvotes: 2

Abin Abraham
Abin Abraham

Reputation: 517

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

Upvotes: 0

dyeray
dyeray

Reputation: 1086

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!

Upvotes: 0

Yantra Logistics
Yantra Logistics

Reputation: 308

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__"

Upvotes: 0

Related Questions