В DRF как можно правильно отобразить связанное поле имени из одной модели внутри другой?

#django #django-models #django-rest-framework

#django #django-модели #django-rest-framework

Вопрос:

Я пытаюсь отобразить всю doctors эту работу на определенном clinic уровне, но продолжаю получать clinic.Doctor.None . Я пытаюсь получить список идентификаторов или имен врачей там

http://localhost:8000/api/clinic / результаты

 [
    {
        "id": 1,
        "doctors": "clinic.Doctor.None", //how to show list of ids or names here?
        "name": "Clinic number 1",
    },
    ...
]
  

Так я реализовал свои модели, сериализаторы и наборы представлений:

 class Clinic(models.Model):
    name = models.CharField(max_length=200)

class Doctor(models.Model):
    clinic = models.ManyToManyField(Clinic, related_name="doctors")
  
 class ClinicSerializer(serializers.ModelSerializer):
    doctors = serializers.CharField(read_only=True)    
    class Meta:
        model = Clinic
        fields = '__all__'

class DoctorSerializer(serializers.ModelSerializer):
    class Meta:
        model = Doctor
        fields = '__all__'
  
 class ClinicViewset(viewsets.ModelViewSet):
    queryset = Clinic.objects.all()
    serializer_class = ClinicSerializer

class DoctorViewset(viewsets.ModelViewSet):
    queryset = Doctor.objects.all()
    serializer_class = DoctorSerializer
  

Ответ №1:

Решение 1: использовать StringRelatedField

 class ClinicSerializer(serializers.ModelSerializer):
    doctors = serializers.StringRelatedField(many=True)

    class Meta:
        model = Clinic
        fields = '__all__'  

Решение 2: использовать SerializerMethodField

 class ClinicSerializer(serializers.ModelSerializer):
    doctors = serializers.SerializerMethodField()

    def get_doctors(self, clinic):
        return clinic.doctors.values_list("name", flat=True) # You can use any valid field name instead of `name` here

    class Meta:
        model = Clinic
        fields = '__all__'  

Я бы выбрал SerializerMethodField over StringRelatedField , поскольку это дает нам больше контроля над данными, которые мы хотим вернуть из поля.

Комментарии:

1. clinic.doctors.values_list("name", flat=True) как я могу вернуть здесь как «name», так и «last_name»?

2. values_list("field_1", "field_2", flat=True)

3. последний вопрос, values_list("field_1", "field_2") возвращает массив массивов. Как я могу изменить это на список объектов?

4. Вы не можете этого сделать.

5. могу ли я тогда получить только массив идентификаторов (идентификатор каждого врача)?