在DRF中,如何序列化从ad-hot路由检索到的数据?

时间:2019-06-17 19:23:29

标签: python django serialization django-rest-framework

我有以下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'

如何序列化此自定义查询集?

1 个答案:

答案 0 :(得分:-1)

这里有很多问题。

首先,正如我之前对您所说的,您不应该使用values。将约会查询集直接传递给序列化器。

第二,您的源名称在序列化器字段中错误。字段doctorpatient均用小写字母定义,因此这是您应在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)
        ...