不同类型用户之间的多对多关系 - Django

Many to Many relationship between different types of users - Django

我正在构建一个包含医疗保健信息系统的玩具项目。我想要两种类型的用户:患者和医生。一个病人可以有多个医生,一个医生可以有多个病人。表示这种关系的最佳方式是什么?

目前我有类似的东西:

class User(AbstractUser):
    def serialize(self):
        return {
            "id": self.id,
            "username": self.username,
        }

class Doctor(models.Model):
    user = models.ForeignKey(User, on_delete=models.SET(get_sentinel_user))
    patients = models.ManyToManyField(Patient)

class Patient(models.Model):
    user = models.ForeignKey(User, on_delete=models.SET(get_sentinel_user))
    doctors = models.ManyToManyField(Doctor)

但是我很确定这行不通。使用 Django 模型表示这种关系的正确方法是什么?谢谢!

跳过医生那里的 many2many。你可以通过病人得到病人的医生。 通过 .add 你可以为病人设置医生

问题陈述

长期使用 ManyToManyRelationship (M2M) 会导致很多问题 运行,从为医生序列化患者开始,有效地为患者序列化医生。

使用两个相关模型的外键为模型中的每个 M2M 关系创建一个单独的数据库 table。这个table在Django中也是无法访问的,无法进一步操作。

所以会有两个数据库定义特定医生与特定患者的关系。保持这两种关系可能会导致长运行中的差异。另外,获取信息不是一个统一的任务。

如果您尝试 create/update 信息,这也会产生问题,因为处理嵌套数据会很复杂。

解决方案

最佳解决方案是遵循 RESTful API 范式。

我们将删除 class DoctorPatient 中的所有 M2M 关系,然后在 models.py 中创建一个新模型来定义 doctor-patient关系:

class Doctor(models.Model):
    user = models.ForeignKey(User, on_delete=models.SET(get_sentinel_user))

class Patient(models.Model):
    user = models.ForeignKey(User, on_delete=models.SET(get_sentinel_user))

class DoctorPatient(models.Model):
    doctor = models.ForeignKey(Doctor)
    patient = models.ForeignKey(Patient)

现在,每当

  • 一个新病人被分配给一个医生,或者
  • 一位新医生被分配给一位患者

然后,可以通过创建 class DoctorPatient.

的实例来建立新的 patient-doctor 关系

我们取得了什么成果

DoctorPatient 模型为由 M2M 关系创建的数据库 table 建立了一个可访问的模型。它还在一个地方处理这种关系。

现在,如果您希望创建两个单独的 APIs 以通过 ID 查找给定关系,则可以创建两个单独的 Django ViewSets:

  • 一个,对于拥有所有患者的医生
  • 其他,一个病人有所有的医生。

假设模型 DoctorPatient 作为 DoctorPatientSerializer 有一个 django 序列化程序,可以在 api.py 中将视图集定义为:

from rest_framework import viewsets

class DoctorWithPatientsViewSet(viewsets.ModelViewSet):
    serializer_class = serializers.DoctorPatientSerializer
    filter_backends = (DjangoFilterBackend,)
    filterset_fields = "__all__"
    lookup_field = 'doctor'

    def get_queryset(self):
        queryset = models.DoctorPatient.objects.all()
        return DoctorPatient.objects.filter(id__in=queryset.values_list('doctor_id',flat=True))

class PatientWithDoctorsViewSet(viewsets.ModelViewSet):
    serializer_class = serializers.DoctorPatientSerializer
    filter_backends = (DjangoFilterBackend,)
    filterset_fields = "__all__"
    lookup_field = 'patient'

    def get_queryset(self):
        queryset = models.DoctorPatient.objects.all()
        return DoctorPatient.objects.filter(id__in=queryset.values_list('patient_id',flat=True))