Django Регистрация двух разных типов пользователей с разными полями - PullRequest
1 голос
/ 20 марта 2019

Я хочу создать двух пользователей: patient и doctor. Оба пользователя будут использовать некоторые стандартные поля, такие как first_name, last_name и т. Д. Однако они должны иметь разные поля. Например, только у doctor будут поля типа expertise и days_available.

Я рассмотрел похожий вопрос, но он не совсем соответствует тому, что мне нужно. Я не обязательно нуждаюсь в пользовательских разрешениях / аутентификации, поскольку мне просто нужны отдельные поля для каждого пользователя. Я пробовал последний подход, расширяя модель пользователя, но когда я создаю пользователя, он не связан с пациентом / врачом. Я должен вручную создать врача и связать его с пользователем. Как автоматически создать доктора / пациента при создании пользователя?

class User(AbstractUser):
    is_doctor = models.BooleanField(default=False)
    is_patient = models.BooleanField(default=False)

class Patient(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    user.is_patient = True
    pid = models.AutoField(unique=True, primary_key=True) #patient identification

class Doctor(models.Model):
    upin = models.AutoField(primary_key=True) #unique physician identification number
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    user.is_doctor = True
    expertise = models.CharField(max_length=20)
    days_available = models.DateTimeField(null=True)

Ответы [ 2 ]

2 голосов
/ 20 марта 2019

Ознакомьтесь с этим сообщением в блоге , в частности, со вторым вариантом: «Расширение пользовательской модели с помощью ссылки« один на один ».» Автор рекомендует использовать сигналы для автоматического выполнения действий при создании / обновлении объекта User. Может быть, попробовать что-то вроде этого:

class User(AbstractUser):
    is_doctor = models.BooleanField(default=False)
    is_patient = models.BooleanField(default=False)

class Patient(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    user.is_patient = True
    pid = models.AutoField(unique=True, primary_key=True) #patient identification

class Doctor(models.Model):
    upin = models.AutoField(primary_key=True) #unique physician identification number
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    user.is_doctor = True
    expertise = models.CharField(max_length=20)
    days_available = models.DateTimeField(null=True)

@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    if created:
        if instance.is_patient:
            Patient.objects.create(user=instance)
        elif instance.is_doctor:
            Doctor.objects.create(user=instance)

@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
    if instance.is_patient:
        instance.patient.save()
    elif instance.is_doctor:
        instance.doctor.save()
1 голос
/ 20 марта 2019

В вашей модели User по умолчанию objects установлено значение auth.models.UserManager. Вы должны переопределить этот метод:

class User(AbstractUser):
    ... # fields
    objects = MedicalUserManager()

class MedicalUserManager(models.UserManager):
    def create_user(self, username, email=None, password=None, **extra_fields):
        # pop all fields you want to use for `Doctor` or `Patient` from `extra_fields`
        doctor_pin = extra_fields.pop('doctor_pin', None)
        pid = extra_fields.pop('pid', None)
        user = super().create_user(username, email, password, **extra_fields)
        if doctor_pin:
            doctor = Doctor.objects.create(user=user, upin=doctor_pin)
            user.is_doctor = True  # not needed if `is_doctor` is in `extra_fields` because it would have been saved when creating the `User`
            user.save()
        elif pid:
            patient = Patient.objects.create(user=user, pid=pid)
            user.is_patient = True
            user.save()
        return user
...