Search code examples
djangodjango-modelsdjango-users

Django Registering two different types of users with different fields


I want to create two users: patient and doctor. Both users will share some of the standard fields like first_name, last_name, etc. However, they should have different fields. Only the doctor, for example, will have fields like expertise and days_available.

I reviewed a similar question but it doesn't quite address what I need specifically. I don't necessarily need custom permissions/authentication as I simply need separate fields for each user. I've tried the last approach, extending the user model, but when I create the the user, it's not linked to the patient/doctor. I have to manually create a doctor and the link it to the user. How can the doctor/patient be automatically created when a user is created?

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)

Solution

  • Check out this blog post--specifically the second option: "Extending the User Model using a One-to-One link." The author recommends using signals to perform actions automatically when a User object is created/updated. Maybe try something like this:

    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()