Отсутствующие поля вложенного сериализатора

Я использую DRF's ModelSerializer и вложенные отношения. Проблема заключается в том, что во вложенном сериализаторе моделей некоторые поля, определенные и видимые при листинге вложенного сериализатора, не отображаются при листинге родительского.

Модели:

class customer(models.Model):
    cstid = models.AutoField(primary_key=True, unique=True)
    name = models.CharField(max_length=35, blank=False)
    ...SNIPPED

    class Meta:
        unique_together = ["name", "mobile", "linkedclinic"]
        ordering = ['name']

    def __str__(self):
        return self.name    
    
class Procedure(models.Model):
    procid = models.AutoField(primary_key=True, unique=True)
    timestr = models.DateTimeField(default=timezone.now)
    template = models.ForeignKey(
        ProcedureTemplate, on_delete=models.CASCADE, blank=True, null=True)
    clinic = models.ForeignKey(Clinic, on_delete=models.CASCADE)
    doctor = models.ForeignKey(
        doctor, on_delete=models.SET_NULL, blank=True, null=True)
    customer = models.ForeignKey(
        customer, on_delete=models.CASCADE, null=False, related_name='procedures')

    def __str__(self):
        return f'{self.template} for {self.customer} on {self.timestr}'

    def eventtime(self):
        class_date = timezone.localtime(self.timestr)
        return class_date.strftime("%d-%m-%Y %I:%M %p")    

Сериализаторы:

class FindingSerializer(serializers.ModelSerializer):
    class Meta:
        model = Finding
        depth = 1
        fields = [
            'fid',
            'fieldheading',
            'value',
            'linkedprocedure',
        ]
        
class ProcedureSerializer(serializers.ModelSerializer):
    finding_proc = FindingSerializer(many=True, read_only=True)
    
    class Meta:
        model = Procedure
        depth = 2
        fields = [
            'procid',
            'timestr',
            'template',
            'clinic',
            'doctor',
            'customer',
            'eventtime',
            'finding_proc',
        ]
        
class customerSerializer(ConvertNoneToStringSerializerMixin, serializers.ModelSerializer):
    def get_unique_together_validators(self):
        """Overriding method to disable unique together checks"""
        return []

    class Meta:
        model = customer
        depth = 3
        biovar_data = Biovariable_dataSerializer(
            read_only=True, many=True)  # many=True is required
        procedures = ProcedureSerializer(
            read_only=True, many=True)  # many=True is required
        # allergies = allergiesSerializer(
        #     read_only=True, many=True)  # many=True is required
        fields = [
            'cstid',
            'date_of_registration',
            'insurance_number',
            'name',
            'age',
            'ageyrs',
            'agemnths',
            'dob',
            'gender',
            'maritalstatus',
            'mobile',
            'alternate',
            'email',
            'address',
            'city',
            'occupation',
            'bloodgroup',
            'linkedclinic',
            'allergies_data',
            'biovar_data',
            'procedures'
        ]
        validators = []
        none_to_str_fields = ('insurance_number', )

Если я отображаю экземпляр процедуры: GET /api/procedures/209/, все необходимые поля отображаются:

Но если я попытаюсь просмотреть сериализатор customerSerializer, который вложен в ProcedureSerializer, все поля ProcedureSerializer не отображаются:

`GET /api/customer/5596/`

{
    "cstid": 5596,
    "name": "Some name",
    "age": "10yr",
    "ageyrs": 9,
    SNIPPED
    "linkedclinic": {},
    "procedures": [
        {
            "procid": 209,
            "timestr": "2022-02-02T17:23:55.048232+05:30",
            "template": {
                "templid": 1,
                "title": "DNE",
                "description": "Diagnostic Nasal Endoscopy",
                "clinic": {
                    "clinicid": 10,
                    "SNIP
                }
            },
            "clinic": {
                "clinicid": 21,
                SNIP
            },
            "doctor": {
                "docid": 4,
                SNIP
            },
            "customer": {
                "cstid": 5596,
                "date_of_registration": "2021-12-25",
                SNIP
                }
            }
        }
    ]
}

Так, отмечается, что два из тех полей, которые есть в ProcedureSerializer, включая eventtime (который на самом деле является методом модели) и finding_proc (который является вложенным сериализатором), отсутствуют в ProcedureSerializer.

repr(ProcedureSerializer()) gives:

"ProcedureSerializer():\n    procid = IntegerField(read_only=True)\n    timestr = DateTimeField(required=False)\n    template = PrimaryKeyRelatedField(allow_null=True, queryset=ProcedureTemplate.objects.all(), required=False)\n    clinic = PrimaryKeyRelatedField(queryset=Clinic.objects.all())\n    doctor = PrimaryKeyRelatedField(allow_null=True, queryset=doctor.objects.all(), required=False)\n    customer = PrimaryKeyRelatedField(queryset=customer.objects.all())\n    eventtime = ReadOnlyField()\n    finding_proc = FindingSerializer(many=True, read_only=True):\n        fid = IntegerField(read_only=True)\n        fieldheading = NestedSerializer(read_only=True):\n            procid = IntegerField(read_only=True)\n            name = CharField(max_length=200)\n            default = CharField(max_length=1000)\n            sortorder = IntegerField(max_value=2147483647, min_value=-2147483648, required=False)\n            fieldtype = ChoiceField(choices=(('heading1', 'Heading1'), ('heading2', 'Heading2')), required=False)\n            template = PrimaryKeyRelatedField(queryset=ProcedureTemplate.objects.all())\n        value = CharField(allow_blank=True, max_length=5000, required=False)\n        linkedprocedure = NestedSerializer(read_only=True):\n            procid = IntegerField(read_only=True)\n            timestr = DateTimeField(required=False)\n            template = PrimaryKeyRelatedField(allow_null=True, queryset=ProcedureTemplate.objects.all(), required=False)\n            clinic = PrimaryKeyRelatedField(queryset=Clinic.objects.all())\n            doctor = PrimaryKeyRelatedField(allow_null=True, queryset=doctor.objects.all(), required=False)\n            customer = PrimaryKeyRelatedField(queryset=customer.objects.all())"

Что здесь происходит? Как я могу получить все поля во вложенном родительском сериализаторе?

Проблема возникла из-за того, что я включил ссылку на вложенный сериализатор в класс Meta, а не в основной класс. На проблему указал @Smixi на Github (Все заслуги принадлежат ему. Я публикую ответ, чтобы он мог помочь другим людям, которые могут совершить ту же ошибку, что и я)

Правильным кодом будет:

class customerSerializer(ConvertNoneToStringSerializerMixin, serializers.ModelSerializer):
    procedures = ProcedureSerializer(
            read_only=True, many=True)  # many=True is required
    biovar_data = Biovariable_dataSerializer(
            read_only=True, many=True)  # many=True is required
    
    def get_unique_together_validators(self):
        """Overriding method to disable unique together checks"""
        return []

    class Meta:
        model = customer
        depth = 3
        fields = [
            'cstid',
            'date_of_registration',
            'insurance_number',
            'name',
            'age',
            'ageyrs',
            'agemnths',
            'dob',
            'gender',
            'maritalstatus',
            'mobile',
            'alternate',
            'email',
            'address',
            'city',
            'occupation',
            'bloodgroup',
            'linkedclinic',
            'allergies_data',
            'biovar_data',
            'procedures'
        ]
        validators = []
Вернуться на верх