Как создать DRF-обратный Глубоко вложенный (глубина : 4) объект Json?

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

Вопрос:

Как достичь проектного сотрудника, Сотрудника, специализации сотрудников, доступного рабочего поля через единый API проекта? Все они связаны многими и многими отношениями.

Здесь я показываю короткий код модели:

 class Project(models.Model):
    title = models.CharField(max_length=300, primary_key=True, unique=True)


class Employee(models.Model):
    name = models.CharField(max_length=300, blank=True, null=True)


class AvailableWorkField(models.Model):
    available_field_position = models.CharField(max_length=100)


class EmployeeSpecialization(models.Model):
    employee = models.ForeignKey(Employee, related_name='employee_specialization_employee', on_delete=models.CASCADE)
    preferred_field = models.ForeignKey(AvailableWorkField, related_name='employee_specialization_available_work_field',
                                        on_delete=models.CASCADE)


class ProjectEmployee(models.Model):
    project = models.ForeignKey(Project, related_name='project_employee_project', on_delete=models.CASCADE)
    employee = models.ForeignKey(Employee, related_name='project_employee_employee', on_delete=models.CASCADE)
    project_position = models.CharField(max_length=100)
 

Вот мой сериализатор:

 class AvailableWorkFieldSerializers(serializers.ModelSerializer):
    class Meta:
        model = AvailableWorkField
        fields = '__all__'


class EmployeeSpecializationSerializers(serializers.ModelSerializer):
    employee_specialization_available_work_field = AvailableWorkFieldSerializers(many=True, read_only=True)

    class Meta:
        model = EmployeeSpecialization
        fields = '__all__'


class EmployeeSerializers(serializers.ModelSerializer):
    employee_specialization_employee = EmployeeSpecializationSerializers(many=True, read_only=True)

    class Meta:
        model = Employee
        fields = '__all__'


class ProjectEmployeeSerializers(serializers.ModelSerializer):
    project_employee_employee = EmployeeSerializers(many=True, read_only=True)

    class Meta:
        model = ProjectEmployee
        fields = '__all__'


class ProjectSerializers(serializers.ModelSerializer):
    project_employee_project = ProjectEmployeeSerializers(many=True, read_only=True)

    class Meta:
        model = Project
        fields = '__all__'
 

Мне нужен сложный вложенный объект JSON, подобный этому, для project rest API:

 [
  {
    "title": "RevSurvey",
    "project_employee_project": [
      {
        "id": 2,
        "project_position": "Django",
        "project": "RevSurvey",
        "employee": {
          "id": 1,
          "name": "david",
          "preferred_field": [
            {
              "id": 1,
              "available_field_position": "Laravel"
            }
          ]
        }
      }
    ]
  }
]
 

Но я ожидал, что получу:

 [
  {
    "title": "RevSurvey",
    "project_employee_project": [
      {
        "id": 2,
        "project_position": "Django",
        "project": "RevSurvey",
        "employee": 1
      }
    ]
  }
]
 

Ответ №1:

Попробуйте с этим:

 class ProjectEmployeeSerializers(serializers.ModelSerializer):
    employee = EmployeeSerializers(read_only=True)

    class Meta:
        model = ProjectEmployee
        fields = '__all__'
 

В контексте ProjectEmployee , вы можете получить сотрудника просто employee так . И поскольку это внешний ключ, а не обратная связь, существует только один объект, поэтому вы не можете использовать many=True