如何编写加入模型的序列化器?

时间:2019-10-01 06:07:09

标签: django django-models django-rest-framework django-serializer

我通过以下查询在两个表上应用了联接

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
    },
    ...
]

我尝试了以下操作:

How to join two models in django-rest-framework

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的答案时,出现以下错误:

  尝试获取序列化程序 performance_serializer 上的字段 channelName 的值时,出现

KeyError。序列化器字段的名称可能不正确,且与dict实例上的任何属性或键都不匹配。原始异常文本为:“ channelId”。

2 个答案:

答案 0 :(得分:3)

我设法使其适用于以下情况:

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

话虽这么说,我强烈建议您同时遵守PEPDjango的命名约定。

这是遵循以下约定的代码:

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列的默认名称!它使使用相关模型变得更加混乱,并且可能首先就是您遇到问题的原因(尽管我无法证明这一点)。

答案 1 :(得分:1)

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

root 
|-- count: long (nullable = true) 
|-- df: long (nullable = true) 
|-- docs: long (nullable = true) 
|-- new_function_result: float (nullable = true) 
|-- new_function_result_WithArray: float (nullable = true) 
|-- new_function_result_Vector: float (nullable = true)

+-----+---+----+-------------------+-----------------------------+--------------------------+ 
|count| df|docs|new_function_result|new_function_result_WithArray|new_function_result_Vector|
+-----+---+----+-------------------+-----------------------------+--------------------------+ 
|  138|  5|  10|           4.108459|                     4.108459|                  4.108459| 
|  128|  4|  10|           5.362161|                     5.362161|                  5.362161|
|  112|  3|  10|          6.8849173|                    6.8849173|                 6.8849173|
|  120|  3|  10|           6.967983|                     6.967983|                  6.967983|
|  189|  1|  10|          14.372153|                    14.372153|                 14.372153|  
+-----+---+----+-------------------+-----------------------------+--------------------------+

另外,请修正您的语法。您未遵循pep8标准。

编辑

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

编辑

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')) 部分