Отношения "многие ко многим" между различными типами пользователей - 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-отношения в модели создается отдельная таблица базы данных с внешними ключами двух связанных моделей. Эта таблица также недоступна в Django для дальнейших операций.

Таким образом, существовало бы две базы данных, определяющие отношения конкретного врача и конкретного пациента. Поддержание этих двух отношений могло бы привести к расхождениям в долгосрочной перспективе. Кроме того, получение информации не было бы единой задачей.

Это также создаст проблему, если вы попытаетесь создать/обновить информацию, поскольку обработка вложенных данных будет сложной.

Решение

Лучшее решение - следовать парадигме RESTful API.

Мы отбросим все отношения M2M в классах Doctor и Patient, а затем создадим новую модель в models.py для определения отношений врач-пациент:

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)

Сейчас, когда угодно

  • к врачу прикреплен новый пациент, или
  • к пациенту прикрепляется новый врач

Затем, новые отношения пациент-врач могут быть установлены путем создания экземпляра класса DoctorPatient.

чего мы достигли

Модель DoctorPatient устанавливает доступную модель для таблиц базы данных, которые создавались отношением M2M. Она также обрабатывает это отношение в одном месте.

Теперь можно создать два отдельных Django ViewSet, если вы хотите создать два отдельных API для поиска по ID для заданных отношений:

  • Один, для врача, имеющего всех пациентов
  • Другой, для пациента, имеющего всех врачей.

Предполагая, что для модели DoctorPatient имеется сериализатор django в виде DoctorPatientSerializer, наборы представлений могут быть определены в 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))
Вернуться на верх