In Django : From a Python OO perspective if I want different types of users shouldn’t I have a “Teacher” Object Type AND “Student” Object” type extended from AbstractUser?
Looks like all the solutions mention to just extend with all the fields required for both users and only use the fields required for a Teacher or Student at Form time. Just trying to stay with the OO method which makes sense to me from a newbie perspective. Having different object types would allow me to test the object for the type instead of looking at an attribute and have only the needed fields for each type defined in the object.
Is there a correct way to do this so I have users of different object types? Could I just embed an object of type Teacher or Student as a field in the User Model? Just a guess? Let me know what you can and thanks for your expert polite response and patience.
Is this a good solution? https://github.com/mishbahr/django-users2
This is the recurring theme I see on the internets… django best approach for creating multiple type users
Advertisement
Answer
This is a bit like assigning a profile to a user. The way I’d do it would be a type
field on a custom user model which then created a related model of either Teacher
or Student
depending on that type.
Looking at the age of the code in django-users2
there, I wouldn’t use that with it being 6 or 7 years old. You might read through it & adapt it’s concepts, but I wouldn’t use it as it is.
The way I create profiles associated with a user is through a signal like this;
from django.contrib.auth import get_user_model from django.db.models.signals import post_save from django.dispatch import receiver from ..models import Profile @receiver(post_save, sender=get_user_model()) def auto_create_profile(instance, **kwargs): """ Anytime a User object is created, create the associated Profile object alongside it """ if kwargs.get('created', False): Profile.objects.create( user=instance )
So you might adapt that to check the type as well;
if kwargs.get('created', False): if instance.type == 'teacher': Teacher.objects.create( user=instance )
Then your models just need a link to the user, which makes sense as a OneToOneField
;
class Profile(models.Model): """ Profile model """ class Meta: """ Metadata """ app_label = 'accounts' verbose_name = _('User profile') verbose_name_plural = _('User profiles') user = models.OneToOneField( verbose_name=_('User'), to=settings.AUTH_USER_MODEL, related_name='profile', on_delete=models.CASCADE )