Reputation: 308
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
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
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
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
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