Поле DRF Nested Serializer не отображается
Я пытаюсь получить некоторые данные из двух связанных моделей, однако я не могу (или хотел бы избежать, чтобы быть более точным) изменить модели. Проблема в том, что вложенный сериализатор не возвращает данные первой модели.
У меня есть следующие сериализаторы
class NameSerializer(serializers.ModelSerializer):
class Meta:
model = Microcontrollers
fields = ['name']
class DataCUTSerializer(QueryFieldsMixin, serializers.ModelSerializer):
stationName = NameSerializer(read_only=True)
class Meta:
model = MeasurementsBasic
fields = ['stationName', 'temp', 'hum']
def to_representation(self, instance):
representation = super().to_representation(instance)
return {'timestamp': instance.time_taken,
**representation}
return representation
Эти сериализаторы используют следующие модели
class MeasurementsBasic(models.Model):
microcontroller = models.OneToOneField('Microcontrollers', related_name='measurements_basic', primary_key=True, on_delete=models.CASCADE)
time_taken = models.DateTimeField()
time_received = models.DateTimeField(blank=True, null=True)
frame = models.IntegerField(blank=True, null=True)
temp = models.FloatField(blank=True, null=True)
hum = models.FloatField(blank=True, null=True)
pres = models.FloatField(blank=True, null=True)
co = models.FloatField(blank=True, null=True)
no2 = models.FloatField(blank=True, null=True)
o3 = models.FloatField(blank=True, null=True)
so2 = models.FloatField(blank=True, null=True)
latitude = models.DecimalField(max_digits=9, decimal_places=6, blank=True, null=True)
longitude = models.DecimalField(max_digits=9, decimal_places=6, blank=True, null=True)
altitude = models.DecimalField(max_digits=9, decimal_places=6, blank=True, null=True)
name = models.CharField(max_length=30, blank=True, null=True)
class Meta:
managed = True
db_table = 'measurements_basic'
unique_together = (('microcontroller', 'time_taken'),)
class Microcontrollers(models.Model):
name = models.CharField(max_length=25)
serial_number = models.CharField(max_length=20, blank=True, null=True)
type = models.CharField(max_length=15, blank=True, null=True)
software = models.CharField(max_length=20, blank=True, null=True)
version = models.CharField(max_length=5, blank=True, null=True)
date_installed = models.DateField(blank=True, null=True)
date_battery_last_replaced = models.DateField(blank=True, null=True)
source = models.CharField(max_length=10, blank=True, null=True)
friendly_name = models.CharField(max_length=45, blank=True, null=True)
private = models.IntegerField()
datetime_updated = models.DateTimeField(db_column='DateTime_Updated') # Field name made lowercase.
class Meta:
managed = True
db_table = 'microcontrollers'
verbose_name_plural = "Microcontrollers"
def __str__(self):
return self.friendly_name
Последнее мое мнение
class TestData(generics.ListAPIView):
serializer = DataCUTSerializer
def get_queryset(self):
final = []
allNames = ['SE1','SE3']
for i in range(len(allNames)):
measurements = MeasurementsBasic.objects.select_related('microcontroller').filter(microcontroller__name=allNames[i]).order_by('-time_taken')[:entries]
final = list(chain(final, measurements))
return final
def list(self, request, *args, **kwargs):
res = super(TestData, self).list(request, *args, **kwargs)
res.data = {"stations": res.data}
return res
Ожидаемый результат - получить json с меткой времени, именем, temp и hum. Однако я не получаю имя и вместо него получаю следующее.
{
"stations": [
{
"timestamp": "2022-03-07T14:51:53",
"temp": 16.18,
"hum": 62.596
},
{
"timestamp": "2022-03-07T14:42:48",
"temp": 16.1,
"hum": 62.856
},
{
"timestamp": "2022-03-07T14:52:49",
"temp": 18.43,
"hum": 62.72
},
{
"timestamp": "2022-03-07T14:43:43",
"temp": 18.239,
"hum": 62.134
}
]
}
Я проверил ответ и полученные данные верны. Любая помощь будет принята с благодарностью.
Я думаю, что проблема в том, что вы не передавали данные через сериализатор, попробуйте сделать что-то вроде этого:
views.py
from rest_framework.response import Response
from rest_framework import status
class TestData(generics.ListAPIView):
serializer = DataCUTSerializer
def get_queryset(self):
allNames = ['SE1','SE3']
# use list comprehension to better performance
final = [
chain(final, MeasurementsBasic.objects.select_related('microcontroller').filter(microcontroller__name=allNames[i]).order_by('-time_taken')[:entries]) for i in range(len(allNames))
]
return final
def list(self, request, *args, **kwargs):
serializer = DataCUTSerializer(self.get_queryset(), many=True)
return Response({"stations": serializer.data}, status=status.HTTP_200_OK)