[Django]-Django design question: extending User to make users that can't log in

3👍

The auth app’s User model has a set_unusable_password method; this probably does what you want without requiring the model to be extended.

2👍

The Django default User model has an is_active field.

http://docs.djangoproject.com/en/dev/topics/auth/#django.contrib.auth.models.User.is_active

you probably want to use that.

That way when a teacher decides they want the user to be able to log in, your code would just set the student’s user to is_active=True and vice versa.

Also according to the documentation link above Django’s default authentication form and permission methods check the is_active flag, so that’s some of the work already done for you.

You’d probably need to generate a username for the student as well, but you can easily do that using a slug from the name if that is provided.

The most obvious way for me to differentiate students from teachers would be groups really and Django provides mechanisms for that as well.

👤Hassan

1👍

You might consider making all the students one kind of object – not User – and then supplementing that model with user objects where the teacher has enabled the student to log in. The composition of these two model objects would solve you want fairly cleanly.

👤heckj

0👍

I woud avoid subclassing User. Instead, you might want to create a custom authenticator that allows you to check group membership for login capability.

"""
DummyBackend.py

"""

from django.contrib.auth.models import User, check_password
from django.contrib.auth.backends import RemoteUserBackend
from lecture_feedback.daily.models import Student
class DummyBackend(RemoteUserBackend):
    """
    Dummy authentication module that takes a username and password. The password must match the username.
    """

    def authenticate(self, username=None, password=None):
        """
        The username passed as ``remote_user`` is considered trusted.  This
        method simply returns the ``User`` object with the given username,
        creating a new ``User`` object if ``create_unknown_user`` is ``True``.

        Returns None if ``create_unknown_user`` is ``False`` and a ``User``
        object with the given username is not found in the database.

        """

        try:
            student = Student.objects.get(globalid=username)
        except Student.DoesNotExist:
            return None

        if username != password:
            return
        user = None

        # Note that this could be accomplished in one try-except clause, but
        # instead we use get_or_create when creating unknown users since it has
        # built-in safeguards for multiple threads.
        if self.create_unknown_user:
            user, created = User.objects.get_or_create(username=username)
            if created:
                user = self.configure_user(user)
        else:
            try:
                user = User.objects.get(username=username)
            except User.DoesNotExist:
                pass
        return user


    def configure_user(self, user):
         """
         Configures a user after creation and returns the updated user.

         By default, returns the user unmodified.
         """
         student = Student.objects.get(globalid=user.username)
         user.first_name = student.first_name
         user.last_name = student.last_name
         return user

The Student model could contain a field that indicates if the student is allowed to log in.
Also take a look at http://docs.djangoproject.com/en/dev/howto/auth-remote-user/#attributes.

Leave a comment