如何为连接模型编写序列化程序?

how to write serializer for joined model?

我已经使用以下查询在两个表上应用了连接,

VIEWS.PY

class performance(viewsets.ModelViewSet):

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

    serializer_class = teamwise_lead_performance_serializer

但我无法使用此序列化程序捕获响应,

SERIALIZER.PY

class channel_serializer(serializers.ModelSerializer):
    class Meta:
        model = Channels
        fields = ['channelName']


class performance_serializer(serializers.ModelSerializer):
    tcount = serializers.IntegerField()
    channel = channel_serializer(many=True, read_only=True)

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

实际结果:

[
    {
        "tcount": 88
    },
    {
        "tcount": 25
    },
    {
        "tcount": 31
    },
    ...
]

预期结果:

[
    {
        "channelName": "abc",
        "tcount": 88
    },
    {
        "channelName": "def",
        "tcount": 25
    },
    {
        "channelName": "ghi",
        "tcount": 31
    },
    ...
]

我尝试了以下方法:

Models.py

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

    class Meta:
        db_table = "table1"

class Leads(models.Model):
    id = models.IntegerField(primary_key=True)
    channelId = models.ForeignKey(Channels, on_delete=models.CASCADE, db_column='channelId')

    class Meta:
        db_table = "table2"

为什么没有得到 channelName 响应? 我在这里做错了什么? 谢谢你的建议

编辑

当我尝试 Mehren 的回答时,出现以下错误:

KeyError when attempting to get a value for field channelName on serializer performance_serializer. The serializer field might be named incorrectly and not match any attribute or key on the dict instance.Original exception text was: 'channelId'.

如果只想获取channelName,那么最好使用

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

此外,请修正您的语法。您没有遵循 pep8 标准。

编辑

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

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

编辑

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

从您的视图中删除 .values("channelId__channelName") 部分

我设法让它与以下内容一起工作:

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

话虽这么说,但我强烈建议您遵循这两个 PEP and Django 命名约定。

按照上述约定,您的代码如下所示:

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

主要的收获是不要更改ForeignKey列的默认名称!它使使用相关模型更加混乱,并且可能首先是您出现问题的原因(尽管我无法证明)。