我有以下3种型号:
#Appointment
class Appointment(models.Model):
doctor = models.ForeignKey(
Doctor,
on_delete=models.CASCADE,
related_name='doctor_appointment')
patient = models.ForeignKey(
Patient,
on_delete=models.CASCADE,
related_name='patient_appointment')
scheduled = models.DateTimeField(auto_now_add=True)
# Doctor
class Doctor(models.Model):
user_id = models.TextField(unique=True)
first_name = models.CharField(max_length=100, blank=False)
last_name = models.CharField(max_length=100, blank=False)
# Patients
class Patient(models.Model):
user_id = models.TextField(unique=True)
first_name = models.CharField(max_length=100, blank=False)
last_name = models.CharField(max_length=100, blank=False)
及其各自的3个序列化器:
# Patient Serializer
class PatientSerializer(serializers.ModelSerializer):
# contract_number = serializers.PrimaryKeyRelatedField(queryset=Contract.objects.all())
class Meta:
model = Patient
fields = '__all__'
# Doctor Serializer
class DoctorSerializer(serializers.ModelSerializer):
tariff = serializers.DecimalField(
source='DoctorTariff.amount',
max_digits=6,
decimal_places=2)
class Meta:
model = Doctor
fields = '__all__'
# Appointment Serializer
class AppointmentSerializer(serializers.ModelSerializer):
doctor = serializers.CharField(source='Doctor.user_id')
patient = serializers.CharField(source='Patient.user_id')
service_provided = serializers.CharField(source='ServiceProvided.service')
upcoming = serializers.SerializerMethodField()
class Meta:
model = Appointment
fields = '__all__'
对于我的Appointment
模型,我指定了一条临时路线,该路线将显示即将到来的约会:
class AppointmentViewSet(viewsets.ModelViewSet):
queryset = Appointment.objects.all()
serializer_class = AppointmentSerializer
@action(detail=False, url_path='upcoming/(?P<user_id>[^/.]+)')
def upcoming_appointment(self, request, user_id=None):
try:
queryset = Appointment.objects.filter(patient__user_id=user_id).\
select_related('patient', 'doctor').values('scheduled', doctor_first_name=F('doctor__first_name'),
doctor_last_name=F('doctor__last_name'),
specialty=F('doctor__specialty'),
doctor_address=F('doctor__address'))
#serializer = AppointmentSerializer(queryset, many=True)
# if serializer.is_valid():
except Appointment.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
# If I use serializer.data instead of queryset I get an error
return Response(queryset, status=status.HTTP_200_OK)
此代码可以正常工作,这意味着,如果我按下upcoming
端点,则可以看到所需的输出。
问题#1 :由于在到达此端点时可以看到正确的输出(以JSON格式),所以我仍然需要使用序列化程序吗?
问题2 :当我尝试使用serializer = AppointmentSerializer(queryset, many=True)
和return Response(serializer.data, status=status.HTTP_200_OK)
进行序列化时,出现以下错误:
AttributeError:尝试在序列化程序doctor
上获取字段AppointmentSerializer
的值时,出现AttributeError。
序列化程序字段的名称可能不正确,并且与QuerySet
实例上的任何属性或键都不匹配。
原始异常文本为:'QuerySet'对象没有属性'Doctor'
如何序列化此自定义查询集?
答案 0 :(得分:-1)
这里有很多问题。
首先,正如我之前对您所说的,您不应该使用values
。将约会查询集直接传递给序列化器。
第二,您的源名称在序列化器字段中错误。字段doctor
和patient
均用小写字母定义,因此这是您应在source属性中使用的名称。
所以:
class AppointmentSerializer(serializers.ModelSerializer):
doctor = serializers.CharField(source='doctor.user_id')
patient = serializers.CharField(source='patient.user_id')
...
def upcoming_appointment(self, request, user_id=None):
try:
queryset = Appointment.objects.filter(patient__user_id=user_id).\
select_related('patient', 'doctor')
serializer = AppointmentSerializer(queryset, many=True)
...