Alleh parast
Alleh parast

Reputation: 83

How to have multiple AUTH_USER_MODEL in django

I have two different app that has separate models that inherits from AbstractionBaseUser like below

# in doctor/models.py
...

class Patient(AbstractBaseUser):
    email = models.EmailField(blank=True, unique=True)
    phone_number = models.IntegerField(blank=False, unique=True)
    
    USERNAME_FIELD = 'phone_number'
    REQUIRED_FIELD = ['phone_number', 'email']

...
# in Patient/models.py
...

class Patient(AbstractBaseUser):
    email = models.EmailField(blank=True, unique=True)
    phone_number = models.IntegerField(blank=False, unique=True)

    
    USERNAME_FIELD = 'phone_number'
    REQUIRED_FIELD = ['phone_number', 'email']

...

Both models have different fields

# in settings.py
AUTH_USER_MODEL = [
    'doctor.Doctor',
    'patient.Patient'
]

I tried to do this but in making migration it tells me that it must be a single model

AssertionError: ForeignKey(['doctor.Doctor', 'patient.Patient']) is invalid. First parameter to ForeignKey must be either a model, a model name, or the string 'self'

I read docs but I couldn't find any help

How can I fix this and how can I have multiple AUTH_USER_MODEL

Upvotes: 4

Views: 2697

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476534

how can I have multiple AUTH_USER_MODEL.

You don't. There is one user model. It would also make all procedures more complicated. What if a the same email address occurs in both the Doctor and Patient model? Then how would you log in such person?

You can however make multiple extra models with a ForeignKey to the user model. We can for example use the default user model:

# settings.py

# …
AUTH_USER_MODEL = 'auth.User'
# …

You can of course also specify a basic user model yourself. But it should be one user model.

Then both the Doctor and Patient model can have a one-to-one relation to the User model:

from django.db import models
from django.conf import settings

class Doctor(models.Model):
    user = models.OneToOneField(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE
    )
    # … extra doctor fields …

as well as a patient:

from django.db import models
from django.conf import settings

class Patient(models.Model):
    user = models.OneToOneField(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE
    )
    # … extra patient fields …

You can then check for a user if it is a doctor by accessing the .doctor attribute:

from django.contrib.auth.decorators import login_required

@login_required
def some_view(request):
    try:
        doctor = request.user.doctor
    except AttributeError:
        # … user is not a doctor …
        pass
    pass

This also allows that a User is both a Doctor and a Patient for example. This may look odd at first. But later it is possible that you introduce more roles, and it is not impossible that the same user is assigned multiple roles, for example doctor and supervisor of a department.

Upvotes: 3

Related Questions