如何使用django rest_framework中的直通表序列化自递归多对多模型?

时间:2017-04-04 20:47:42

标签: django serialization django-models django-rest-framework django-serializer

我正在使用django rest框架开发一个rest API,我被困在一个序列化程序中,我的想法是使用直通表来序列化自我递归的多对多模型我的代码是:

model.py:

class Patient(models.Model):
    class Meta:
        db_table = 'patients'

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, unique=True)
    id_card = models.CharField(max_length=45)
    dob = models.DateField()
    gender = EnumChoiceField(enum_class=Gender)
    patientscol = models.CharField(max_length=45)
    fk_user = models.ForeignKey(Users, related_name='user_patient', on_delete=models.CASCADE)
    relative = models.ManyToManyField("self", through='PatientHasRelative')

class PatientHasRelative(models.Model):
    class Meta:
        db_table = 'patients_has_relatives'

    fk_patient = models.ForeignKey(Patient, related_name='patient_has', on_delete=models.CASCADE)
    fk_relative_patient = models.ForeignKey(Patient, related_name='patient_relative', on_delete=models.CASCADE)
    relationship = EnumChoiceField(enum_class=Relationship)

我的serializer.py是:

class PatientSerializer(serializers.ModelSerializer):
    class Meta:
        model = Patient
        fields = ('__all__')

    id = serializers.UUIDField(read_only=True)
    id_card = serializers.CharField(required=True, max_length=45)
    dob = serializers.DateField(required=True)
    gender = EnumChoiceField(enum_class=Gender)
    fk_user = serializers.PrimaryKeyRelatedField(required=True, queryset=Users.objects.all())
    relative = PatientSerializer(read_only=True, required=True)#problem is here i cant use PatientSerializer here

class PatientHasRelativeSerializer(serializers.ModelSerializer):
    class Meta:
        model = PatientHasRelative
        fields = ('__all__')

    fk_patient = serializers.PrimaryKeyRelatedField(required=True, queryset=Patient.objects.all())
    fk_relative_patient = serializers.PrimaryKeyRelatedField(required=True, queryset=Patient.objects.all())
    relationship = EnumChoiceField(enum_class=Relationship)

一点帮助将不胜感激

1 个答案:

答案 0 :(得分:0)

要完成此操作,您需要在源字段的源模型中定义related_name,即添加

class Patient(models.Model):
    relatives = models.ManyToManyField(
        "self", through='PatientHasRelative', related_name='patients')

使用此related_name,您可以轻松访问-在序列化程序中关系的任何一侧添加/删除/设置亲戚/患者 您可以使用中介模型来做到这一点

relative = Patient(**key_value_fields)
patient = Patient(**key_value_field)

PatientHasRelative.objects.create(
 relative=relative, patient=patient, through_defaults=(relationship ='value',))

或者您可以这样做

relative.patients.add(patient, through_defaults=relationship ='value')

或这个

patient.relatives.add(relative, through_defaults=relationship ='value')

示例检索

patient.relatives.all()