ian*_*oad 5 python django serialization django-rest-framework
我有一个数据库表:
servicenumber | meternumber | usagedatetime | usage
11111 | 22222 | 2019-01-01 | 1.85
11111 | 22222 | 2019-01-02 | 2.25
11111 | 22222 | 2019-01-03 | 1.55
11111 | 22222 | 2019-01-04 | 2.15
11111 | 33333 | 2019-02-01 | 2.95
11111 | 33333 | 2019-02-02 | 3.95
11111 | 33333 | 2019-02-03 | 2.05
11111 | 33333 | 2019-02-04 | 3.22
Run Code Online (Sandbox Code Playgroud)
如您所见,一个服务编号可以与多个仪表编号相关联。将服务编号视为不变的地理位置的唯一标识符。
我有一个 Django 模型:
class MeterUsage(models.Model):
objectid = models.IntegerField(
db_column='OBJECTID', unique=True, primary_key=True)
servicenumber = models.IntegerField(
db_column='serviceNumber', blank=True, null=True)
meternumber = models.IntegerField(
db_column='meterNumber', blank=True, null=True)
usagedatetime = models.DateTimeField(
db_column='usageDateTime', blank=True, null=True)
usage = models.DecimalField(
max_digits=38, decimal_places=8, blank=True, null=True)
Run Code Online (Sandbox Code Playgroud)
我有一个基本的序列化程序:
class MeterUsageSerializer(serializers.ModelSerializer):
class Meta:
model = MeterUsage
fields = (
'usagedatetime',
'usage'
)
Run Code Online (Sandbox Code Playgroud)
目前的回应是:
[
{
"usagedatetime": "2019-01-01",
"usage": "1.85"
},
{
"usagedatetime": "2019-01-02",
"usage": "2.25"
},
{
"usagedatetime": "2019-01-03",
"usage": "1.55"
},
....
]
Run Code Online (Sandbox Code Playgroud)
但我真正想要的是(需要用米号分隔的用法):
[
{
"servicenumber": "11111",
"meternumber": "22222",
"usagedata": [
{
"usagedatetime": "2019-01-01",
"usage": "1.85"
},
{
"usagedatetime": "2019-01-02",
"usage": "2.25"
},
{
"usagedatetime": "2019-01-03",
"usage": "1.55"
},
{
"usagedatetime": "2019-01-04",
"usage": "2.15"
},
...
]
},
{
"servicenumber": "11111",
"meternumber": "33333",
"usagedata": [
{
"usagedatetime": "2019-02-01",
"usage": "2.95"
},
{
"usagedatetime": "2019-02-02",
"usage": "3.95"
},
{
"usagedatetime": "2019-02-03",
"usage": "2.05"
},
{
"usagedatetime": "2019-02-04",
"usage": "3.22"
},
...
]
},
...
]
Run Code Online (Sandbox Code Playgroud)
我的最终目标是使用 Angular 7 应用程序中的 ChartJS 库在折线图中显示这些数据,并且数据需要采用以下格式:
chartData = [
{
label: '22222',
data: [1.85, 2.25, 1.55, 2.15]
},
{
label: '33333',
data: [2.95, 3.95, 2.05, 3.22]
}
];
Run Code Online (Sandbox Code Playgroud)
是否可以使用序列化程序来格式化我上面显示的数据?我根据我读过的各种教程尝试了不同的技术,但似乎没有任何效果,现在我只是对如何处理它感到困惑。
任何见解表示赞赏!
如果您不打算更改模型结构,则无法使用 ModelSerializer 执行您想要的操作。使用 ModelSerializer,您可以在每个数据库行的结果列表中获得 1 个项目,但您希望将多行合并为结果列表中的单个项目。但是,您可以尝试选择唯一的 servicenumner -meternumber 对并直接子类Serializer来序列化您的数据。
在您看来:
queryset = MeterUsage.objects.values('servicenumber', 'meternumber').distinct()
return Response(MeterUsageSerializer(queryset, many=True).data)
Run Code Online (Sandbox Code Playgroud)
还有你的串行器:
class MeterUsageSerializer(serializers.Serializer):
servicenumber = serializers.IntegerField()
meternumber = serializers.IntegerField()
usagedata = serializer.SerializerMethodField()
def get_usagedata(self, obj):
return [{
'usagedatetime': item.usagedatetime.strftime('%Y-%m-%d'),
'usage': item.usage
} for item in MeterUsage.objects.filter(servicenumber=obj['servicenumber'], meternumber=obj['meternumber'])]
Run Code Online (Sandbox Code Playgroud)
如果您可以更改模型结构,则可以按以下方式构建模型和序列化器:
class MeterUsage(models.Model):
objectid = models.IntegerField(
db_column='OBJECTID', unique=True, primary_key=True)
servicenumber = models.IntegerField(
db_column='serviceNumber', blank=True, null=True)
meternumber = models.IntegerField(
db_column='meterNumber', blank=True, null=True)
class Meta:
unique_together = ('servicenumber', 'meternumber')
class MeterUsageData(models.Model):
meterusage = models.ForeignKey(MeterUsage, on_delete=models.CASCADE, related_name='data')
usagedatetime = models.DateTimeField(
db_column='usageDateTime', blank=True, null=True)
usage = models.DecimalField(
max_digits=38, decimal_places=8, blank=True, null=True)
class MeterUsageDataSerializer(serializers.ModelSerializer):
usagedatetime = serializers.DateTimeField(format=''%Y-%m-%d'')
class Meta:
model = MeterUsageData
fields = ('usagedatetime', 'usage')
class MeterUsageSerializer(serializers.ModelSerializer):
data = MeterUsageDataSerializer(many=True)
class Meta:
model = MeterUsage
fields = ('servicenumber', 'meternumber', 'data')
Run Code Online (Sandbox Code Playgroud)
使用此模型 - 序列化器结构,您可以在视图中获得如下输出:
queryset = MeterUsage.objects.filter(...)
return Response(MeterUsageSerializer(queryset, many=True).data)
Run Code Online (Sandbox Code Playgroud)
请注意,使用这两种方法时,您都会对每个服务编号 - 计量编号对发出数据库查询。
| 归档时间: |
|
| 查看次数: |
1180 次 |
| 最近记录: |