Попытка получить имена ForeignKey вместо pk в QuerySet Django
Я пытаюсь сделать сложный набор запросов и хочу включить в него имена ForeignKeys
вместо pk. Я использую ajax для получения живой ленты из пользовательских вводов и печати результатов на DataTable
, но я хочу вывести имена вместо пк. Я получаю набор запросов и когда я console.log
его, sensor_name
там нет.
Мои модели выглядят следующим образом:
class TreeSensor(models.Model):
class Meta:
verbose_name_plural = "Tree Sensors"
field = models.ForeignKey(Field, on_delete=models.CASCADE)
sensor_name = models.CharField(max_length=200, blank=True)
class TreeSensorMeasurement(models.Model):
class Meta:
verbose_name_plural = "Tree Sensor Measurements"
sensor = models.ForeignKey(TreeSensor, on_delete=models.CASCADE)
datetime = models.DateTimeField(blank=True, null=True, default=None)
soil_moisture_depth_1 = models.DecimalField(max_digits=15, decimal_places=2)
soil_moisture_depth_2 = models.DecimalField(max_digits=15, decimal_places=2)
soil_moisture_depth_1_filtered = models.DecimalField(max_digits=15, decimal_places=2, blank=True, null=True)
soil_moisture_depth_2_filtered = models.DecimalField(max_digits=15, decimal_places=2, blank=True, null=True)
soil_temperature = models.DecimalField(max_digits=15, decimal_places=2)
А мой вид выглядит следующим образом (я опустил несущественный код):
field_list = Field.objects.filter(user=request.user)
tree_sensors = TreeSensor.objects.filter(field_id__in=field_list.values_list('id', flat=True))
statSensors = (TreeSensorMeasurement.objects
.filter(sensor_id__in=tree_sensors.values_list('id', flat=True))
.filter(datetime__date__lte=To_T[0]).filter(datetime__date__gte=From_T[0])
.filter(soil_moisture_depth_1__lte=To_T[1]).filter(soil_moisture_depth_1__gte=From_T[1])
.filter(soil_moisture_depth_2__lte=To_T[2]).filter(soil_moisture_depth_2__gte=From_T[2])
.filter(soil_temperature__lte=To_T[3]).filter(soil_temperature__gte=From_T[3])
.order_by('sensor', 'datetime'))
Код выше работает правильно, но я не могу понять, что нужно сделать, чтобы получить во фронтенде вместо pk имя TreeSensors
. Пример того, как я получаю один экземпляр во фронтенде:
datetime: "2022-11-20T13:28:45.901Z"
sensor: 2
soil_moisture_depth_1: "166.00"
soil_moisture_depth_1_filtered: "31.00"
soil_moisture_depth_2: "171.00"
soil_moisture_depth_2_filtered: "197.00"
soil_temperature: "11.00"
Поскольку sensor_name находится на другом конце поля внешнего ключа в вашем объекте TreeSensorMeasurement, вы можете взять его с помощью select_related, как в
.filter(soil_temperature__lte=To_T[3]).filter(soil_temperature__gte=From_T[3])
.select_related('sensor')
.order_by('sensor', 'datetime'))
В шаблоне вы можете ссылаться на него, без дальнейших поисков в БД, как
{% for ss in statsensors }}
{{ ss.sensor.sensor_name }}
{% endfor }}
Если вы используете Django Rest Framework, вам нужно будет сделать немного больше - это взято из примера DRF nested relationshipos
class TreeSensorSerializer(serializers.ModelSerializer):
class Meta:
model = TreeSensor
fields = ['sensor_name']
class TreeSensorMeasurementSerializer(serializers.ModelSerializer):
sensor = TreeSensorSerializer(read_only=True)
class Meta:
model = TreeSensorMeasurement
fields = ['sensor',
'datetime',
'soil_moisture_depth1',
'soil_moisture_depth2',
'soil_temoperature',
]
Попробуйте добавить поле сериализатора только для чтения в TreeSensorMeasurementSerializer
sensor_name = serializer.ReadOnlyField(source='sensor.sensor_name')