Django 如何为联接模型编写序列化程序?
我已使用以下查询在两个表上应用了join 视图.PYDjango 如何为联接模型编写序列化程序?,django,django-models,django-rest-framework,django-serializer,Django,Django Models,Django Rest Framework,Django Serializer,我已使用以下查询在两个表上应用了join 视图.PY class performance(viewsets.ModelViewSet): queryset = Leads.objects.select_related('channelId' ).values("channelId__channelName").annotate(tcount=Count('channelId')) serializer_class = teamwise_lead_perform
class performance(viewsets.ModelViewSet):
queryset = Leads.objects.select_related('channelId'
).values("channelId__channelName").annotate(tcount=Count('channelId'))
serializer_class = teamwise_lead_performance_serializer
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']
但我无法使用此序列化程序捕获响应
序列化程序.PY
class performance(viewsets.ModelViewSet):
queryset = Leads.objects.select_related('channelId'
).values("channelId__channelName").annotate(tcount=Count('channelId'))
serializer_class = teamwise_lead_performance_serializer
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
},
...
]
我尝试了以下方法:
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
型号.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的答案时,我得到以下错误:
尝试获取序列化程序性能\u序列化程序上的字段channelName的值时出现键错误。序列化程序字段的名称可能不正确,并且与dict实例上的任何属性或键都不匹配。原始异常文本为:“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'))
编辑
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\uu 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
话虽如此,我还是强烈建议您遵循命名和命名惯例
下面是您的代码的外观,如下所述:
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
列的默认名称!这使得使用相关模型变得更加混乱,并且可能是您出现问题的首要原因(尽管我无法证明这一点) 如果我添加channelName=serializers.CharField(source='channel.name')
?在performance_serializer中,它为我提供了字段“channel”已在serializer performance_serializer上声明,但尚未包含在“fields”选项中。
。。。。。。。我在问题中添加了模型我编辑了答案。基本上,对于DRF序列化程序,您手动定义的字段也必须存在于Meta.fields中。现在,在尝试获取序列化程序“performance\u serializer”上的字段“channelName”的值时,我遇到了get keyrorm。\n序列化程序字段的名称可能不正确,并且与“dict”实例上的任何属性或键都不匹配。\n原始异常文本为:“频道”。
我已经根据您的型号定义编辑了答案。希望有帮助!试图获取序列化程序“performance\u serializer”上字段“channelName”的值时,getingget-KeyError仍然存在。序列化程序字段的名称可能不正确,并且与“dict”实例上的任何属性或键都不匹配。原始异常文本为:“channelId”。
您在Lead
模型中有一个输入错误,在channel
字段中:相关型号名称应为channel
now。它只有一个字符,编辑必须更改至少6个字符,所以我必须找到其他东西来挑剔。。。最好自己解决:)还要注意,每个潜在客户只能有一个相关频道。因此,设置channel=channel\u序列化程序(many=True,…)
没有意义-这里不能有很多通道。正如所提供的答案所表明的那样,把它变成查尔菲尔德是一个更好的主意。