3

I'm trying to get the same output as my django query but the actual output differs when Django Rest Framework serves it. Added the following to my serializer but it kept leaving out the cart_assessments__risk_type out of the output. How do I make my django rest framework serializer output match my django query output?

models.py:

from django.db import models

class TrainAssessment(models.Model):
    train_name = models.CharField(max_length=30)


class CartAssessment(models.Model):
    train_assessment = models.ForeignKey(TrainAssessment, on_delete=models.CASCADE, related_name='cart_assessments')
    risk_type = models.CharField(max_length=30)

views.py

from rest_framework import viewsets, mixins

class SubwayTrainDetailsViewSet(viewsets.GenericViewSet,
                            mixins.ListModelMixin,
                            mixins.CreateModelMixin):
    queryset = TrainAssessment.objects.values('cart_assessments__risk_type').annotate(
        cart_count=Count('cart_assessments__risk_type')).order_by('-cart_count').annotate(
        train_count=Count('id', distinct=True))
    serializer_class = serializers.SubwayTrainDetailsViewSetSerializer

serializers.py

from rest_framework import serializers

class SubwayTrainDetailsViewSetSerializer(serializers.ModelSerializer):
    train_count = serializers.IntegerField()
    cart_count = serializers.IntegerField()
    cart_assessments__risk_type = serializers.RelatedField(source="cartassessment.risk_type", read_only=True)

    class Meta:
        model = TrainAssessment
        fields = ('id', 'cart_assessments__risk_type', 'train_count', 'cart_count')

Im trying to make my serializer provide the same output as below:

#QUERY
queryset = TrainAssessment.objects.values('cart_assessments__risk_type').annotate(
    cart_count=Count('cart_assessments__risk_type')).order_by('-cart_count').annotate(
    train_count=Count('id', distinct=True))

#OUTPUT I WANT THAT COMES FROM ABOVE QUERY:
{'cart_assessments__risk_type': '', 'cart_count': 55, 'train_count': 14}
{'cart_assessments__risk_type': 'door', 'cart_count': 22, 'train_count': 13}
{'cart_assessments__risk_type': 'wheel', 'cart_count': 8, 'train_count': 8}
{'cart_assessments__risk_type': 'frame', 'cart_count': 1, 'train_count': 1}
{'cart_assessments__risk_type': 'floors', 'cart_count': 1, 'train_count': 1}
{'cart_assessments__risk_type': 'windows', 'cart_count': 1, 'train_count': 1}
{'cart_assessments__risk_type': 'straphanger', 'cart_count': 1, 'train_count': 1}

Actual Output missing cart_assessments__risk_type from Django Rest Framework when hitting the endpoint/route for SubwayTrainDetailsViewSet:

# OUTPUT MISSING `cart_assessments__risk_type`
[
    {"train_count": 14, "cart_count": 55},
    {"train_count": 13, "cart_count": 22},
    {"train_count": 8, "cart_count": 8},
    {"train_count": 1, "cart_count": 1},
    {"train_count": 1, "cart_count": 1},
    {"train_count": 1, "cart_count": 1},
    {"train_count": 1,"cart_count": 1}
]

How can I django rest framework serve the output with cart_assessments__risk_type?p

5
  • 2
    What about this? cartassessment__risk_type = serializers.CharField(source='cartassessment__risk_type') ? Commented Mar 4, 2020 at 6:22
  • 1
    You've lost s in the end of the relation name. Commented Mar 4, 2020 at 6:33
  • @tarasinf when trying that I get the following error It is redundant to specify source='cartassessment__risk_type'` on field 'CharField' in serializer 'SubwayTrainDetailsViewSetSerializer', because it is the same as the field name. Remove the source keyword argument.` Commented Mar 4, 2020 at 10:04
  • @IvanStarostin when trying with the s in the source in RelatedField, it did not mention any errors but still didn't show the cart_assessments__risk_type in the output Commented Mar 4, 2020 at 10:08
  • 2
    @DanielPlasRivera quick solution, try by method in serializer, like def get_cart_assessments Commented Mar 4, 2020 at 13:35

1 Answer 1

3

Thanks @tarasinf . I was able to come up with the answer with that solution you mentioned.

class SubwayTrainDetailsViewSetSerializer(serializers.ModelSerializer):
    train_count = serializers.IntegerField()
    cart_count = serializers.IntegerField()
    cart_assessments__risk_type = serializers.SerializerMethodField('get_cart_assessments')

    class Meta:
        model = TrainAssessment
        fields = ('cart_assessments__risk_type', 'train_count', 'cart_count')

    def get_cart_assessments(self, obj):
        return obj.get('cart_assessments__risk_type')
Sign up to request clarification or add additional context in comments.

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.