让我们试着分析一下这里的情况。我们需要用列表输入温度数据。因此,让我们为此目的使用ListField。所以,我们应该这样开始:
class PatientSerializer(ModelSerializer):
temperatures = ListField(child=FloatField())
这将做的是期待用户的浮动列表。
但是当使用GET 操作时,我们将如何获得创建的患者的温度数组。为此,让我们向该字段添加一个源。 source 参数上写的任何内容都将转换为 patient.field,例如:
class PatientSerializer(ModelSerializer):
temperatures = ListField(child=FloatField(), source="temperature_list")
这个source="temperature_list 将使用patient.temperature_list 并在序列化对象时显示结果。现在让我们为原始模型添加一些属性,以便我们可以像这样获得干净的温度数组:
class Patient(models.Model):
created_at = models.DateField()
name = models.CharField(max_length=200)
updated_at = models.DateField()
@property
def temperature_list(self):
return [temperature.value for temperature in self.temperatures.all()]
我们差不多完成了。现在我们需要覆盖PatientSerializer 的create 方法,以便它可以保存列表中的温度。
现在,要从validated_data 获取温度数据,我们需要使用ListField 的source 参数中使用的相同字段,即temperature_list。因此,我们需要弹出这些数据,创建用户,验证温度列表项,创建与患者相关的温度对象。让我们像这样创建一个TemperatureSerializer:
class TemperatureSerializer(ModelSerializer):
class Meta:
model = Temperature
fields = ("created_at", "value", "updated_at", "patient")
extra_kwargs = {
"patient": {"write_only": True},
"created_at": {"required": False},
"updated_at": {"required": False},
}
现在,我们需要做的就是编写 create 方法。我们可以这样写:
def create(self, validated_data):
temperatures = validated_data.pop("temperature_list")
now = datetime.now().strftime("%Y-%m-%d")
patient = Patient.objects.create(
created_at=now, updated_at=now, **validated_data
)
for temperature in temperatures:
now = datetime.now().strftime("%Y-%m-%d")
temperature_serializer = TemperatureSerializer(
data={
"value": temperature,
"created_at": now,
"updated_at": now,
"patient": patient.id,
}
)
temperature_serializer.is_valid(raise_exception=True)
temperature_serializer.save()
return patient
最后,让我们把所有的东西放在一起,这就是serializers.py 文件的样子:
from rest_framework.serializers import ModelSerializer, ListField, FloatField
from datetime import datetime
from .models import Patient, Temperature
class TemperatureSerializer(ModelSerializer):
class Meta:
model = Temperature
fields = ("created_at", "value", "updated_at", "patient")
extra_kwargs = {
"patient": {"write_only": True},
"created_at": {"required": False},
"updated_at": {"required": False},
}
class PatientSerializer(ModelSerializer):
temperatures = ListField(child=FloatField(), source="temperature_list")
def create(self, validated_data):
temperatures = validated_data.pop("temperature_list")
now = datetime.now().strftime("%Y-%m-%d")
patient = Patient.objects.create(
created_at=now, updated_at=now, **validated_data
)
for temperature in temperatures:
now = datetime.now().strftime("%Y-%m-%d")
temperature_serializer = TemperatureSerializer(
data={
"value": temperature,
"created_at": now,
"updated_at": now,
"patient": patient.id,
}
)
temperature_serializer.is_valid(raise_exception=True)
temperature_serializer.save()
return patient
class Meta:
model = Patient
fields = ("created_at", "name", "temperatures", "updated_at")
extra_kwargs = {
"created_at": {"required": False},
"updated_at": {"required": False},
}
这就是views.py 的样子:
from rest_framework.generics import ListCreateAPIView, ListAPIView
from .models import Patient, Temperature
from .serializers import PatientSerializer, TemperatureSerializer
class PatientListCreateView(ListCreateAPIView):
serializer_class = PatientSerializer
queryset = Patient.objects.all()
class TemperatureListView(ListAPIView):
serializer_class = TemperatureSerializer
def get_queryset(self, *args, **kwargs):
patient_id = self.kwargs["pk"]
return Temperature.objects.filter(patient_id=patient_id)
还有urls.py 文件:
from django.urls import path
from . import views
urlpatterns = [
path("patients", views.PatientListCreateView.as_view(), name="patient-list"),
path(
"patients/<int:pk>/temperatures/",
views.TemperatureListView.as_view(),
name="patient-temperature-list",
),
]
POST 方法的工作原理如下:
这就是患者体温恢复的方式:
我希望这能回答你的问题。