如何为连接模型编写序列化程序?
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
列的默认名称!它使使用相关模型更加混乱,并且可能首先是您出现问题的原因(尽管我无法证明)。
我已经使用以下查询在两个表上应用了连接,
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
列的默认名称!它使使用相关模型更加混乱,并且可能首先是您出现问题的原因(尽管我无法证明)。