2

As title, I have 3 types of User and each User can have more than one role.

from django.contrib.auth.models import AbstractUser, User
from django.db import models
from django.db.models import CASCADE
from hospital.models import Hospital

class Role(models.Model):
    '''
  The Role entries are managed by the system,
  automatically created via a Django data migration.
  '''
    DOCTOR = 1
    DIRECTOR = 2
    PATIENT = 3

    ROLE_CHOICES = (
        (DOCTOR, 'doctor'),
        (DIRECTOR, 'director'),
        (PATIENT, 'patient'),

    )

    id = models.PositiveSmallIntegerField(choices=ROLE_CHOICES, primary_key=True)

    def __str__(self):
        return self.get_id_display()


class User(AbstractUser):
    roles = models.ManyToManyField(Role)

    def __str__(self):
        return self.roles


class Doctor(models.Model):
    # role = models.OneToOneField(User, on_delete=CASCADE)
    career = models.TextField(blank=True, max_length = 1000)

class Director(models.Model):
    # role = models.OneToOneField(User, on_delete=CASCADE)
    members = models.ManyToManyField(Doctor)

class Patient(models.Model):
    # personal information like above.

https://simpleisbetterthancomplex.com/tutorial/2018/01/18/how-to-implement-multiple-user-types-with-django.html

I'm creating a model, but I do not know how to set the key.

I made it by referring to the above site. The director owns the doctor and can authorize it.

But I do not know how to give a key to a doctor or director.

If you I to comment, I get an error.

I hope you can help me.

Jiwon Kim
  • 139
  • 3
  • 12

1 Answers1

1

Assuming that you want to set the default roles for the 3 derived classes.

Taking slight inspiration from this post.

Since roles is a many-to-many relation, you can override the model's save method (you can use signals for this as well, but wouldn't recommend that in your case).

e.g.

class Doctor(models.Model):

    def save(self, *args, **kwargs):
        if not self.id: # object creation
            should_add_role = True
        super(Doctor, self).save(*args, **kwargs) # do the usual
        if should_add_role: # add our defaults
            self.roles.add(Role.objects.get_or_create(id=Role.DOCTOR))
shad0w_wa1k3r
  • 12,955
  • 8
  • 67
  • 90
  • Thank you for your reply. But I do not know your intentions. Can you explain in more detail? Where should I call the save function? Where should self be defined? – Jiwon Kim Feb 18 '18 at 16:51
  • You don't have to call `.save` explicitly. We're overriding default behaviour to add our custom logic. The method is defined (overriding the default method) under the model class. – shad0w_wa1k3r Feb 18 '18 at 17:04
  • Thank you for your reply. When I create a specific role (eg doctor) in the user model, I want to make DoctorProfile model instance automatically. But I do not know how to do it. Sorry for the inconvenience. – Jiwon Kim Feb 19 '18 at 06:30
  • I don't understand what you mean by that. When & where do you want to create the model instance? And for what purposes? – shad0w_wa1k3r Feb 19 '18 at 07:23
  • Sorry for my insufficient explanation. When i make User model instance automatically, If i create an instance of the User model, i want to make userprofile that corresponds to that role. (for example, i have created a user instance with a role doctor , automatically make doctorprofile instance) what should i do? – Jiwon Kim Feb 19 '18 at 10:06
  • In that case, you should use the `post_save` signal on your user model and according to the role of that instance, create the corresponding profile instance. See this example - https://stackoverflow.com/a/13016982/2689986. – shad0w_wa1k3r Feb 19 '18 at 10:38
  • Thank you for your comment!! – Jiwon Kim Feb 19 '18 at 11:23