[Django]-How to write serializer for joined model?

3πŸ‘

βœ…

I managed to get it working with the following:

class performance_serializer(serializers.ModelSerializer):
    tcount = serializers.IntegerField()
    channelName = serializers.CharField(source='channelId__channelName')

    class Meta:
        model = Leads
        fields = ['tcount', 'channelName']

class performance(viewsets.ModelViewSet):
    queryset = Leads.objects.select_related('channelId'
        ).values("channelId__channelName").annotate(tcount=Count('channelId'))
    serializer_class = performance_serializer

That being said, I would strongly encourage you to follow both PEP and Django naming conventions.

Here is what your code would look like following said conventions:

class Channel(models.Model):
    id = models.IntegerField(primary_key=True)
    channel_name = models.CharField(max_length=20, default=None)

class Lead(models.Model):
    id = models.IntegerField(primary_key=True)
    channel = models.ForeignKey(Channel, on_delete=models.CASCADE)

class PerformanceSerializer(serializers.ModelSerializer):
    channel_count = serializers.IntegerField()
    channel_name = serializers.CharField(source='channel__channel_name')

    class Meta:
        model = Lead
        fields = ['channel_count', 'channel_name']

class PerformanceViewSet(viewsets.ModelViewSet):
    queryset = Lead.objects.select_related('channel'
        ).values("channel__channel_name").annotate(channel_count=Count('channel'))
    serializer_class = PerformanceSerializer

The main takeaway from this is to not change the default name of your ForeignKey columns! It makes working with related models much more confusing, and is possibly the reason for your problem in the first place (although I couldn’t prove it).

πŸ‘€Lord Elrond

1πŸ‘

If you want to only get the channelName, then it’s better to use

channelName = serializers.CharField(source='channelId.channelName') 

Also, please fix your syntax. You are not following the pep8 standards.

EDIT

class PerformanceSerializer(serializers.ModelSerializer):
    tcount = serializers.IntegerField()
    channelName = serializers.CharField(source='channelId.channelName') 

    class Meta:
        model = Leads
        fields = ['tcount', 'channelName']

EDIT

queryset = Leads.objects.select_related('channelId').values("channelId__channelName").annotate(tcount=Count('channelId'))

Remove the .values("channelId__channelName") part from your view

πŸ‘€Mehran

Leave a comment