Skip to content
Advertisement

Django User Type Definition

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
    )
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement