У меня есть 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: Получил AttributeError при попытке получить значение для поля doctor
на сериализаторе AppointmentSerializer
.
Поле сериализатора может иметь неправильное имя и не соответствовать ни одному атрибуту или ключу в экземпляре QuerySet
.
Исходный текст исключения был: объект «QuerySet» не имеет атрибута «Доктор»
Как я могу сериализовать этот пользовательский набор запросов?