Отношения "многие ко многим" между различными типами пользователей - 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))