Django design issue: user extension so that users who cannot log in

The site I'm working on involves teachers creating student objects. The teacher can choose so that the student can log on to the site (to check calendars, etc.), Or the teacher can choose to use the student’s facility only for keeping notes and not allow the student to log in. If the teacher supplies the username and password, he must create an object of the first type - one that can log into the system, that is, a regular user object. If the teacher does not enter a username / password, he must create a second type. Another requirement is that the teacher should be able to enter later and change the student without registration to another level. What is the best development method for this scenario? Subclass User and username and password are not required? What else will it affect?

Edit: I ended up using User.set_unusable_password (). Here is the code - I forgot other forms, etc., which I also use in my opinion:

The form

class StudentForm(forms.ModelForm):
    username = forms.RegexField(regex=r'^\w+$',
                                required=False,
                                max_length=30,
                                label=("Username"),
                                error_messages={ 'invalid': ("This value must contain only letters, numbers and underscores.") })
    password = forms.CharField(widget=forms.PasswordInput(),
                                    label="Password", required=False)

    class Meta:
        model = User
        fields = ('first_name', 'last_name', 'username', 'email', 'password')

Please note that username and password are not required on the form.

View

def create_student(request):
    if request.method == "POST":
        student_form = StudentForm(request.POST)
        if student_form.is_valid():
            user = student_form.save(commit=False)
            if student_form.cleaned_data['username'] == '':
                user.username = generate_random_username()
                user.set_unusable_password()
            else:
                user.set_password(user.password)
            user.save()

            return HttpResponseRedirect(reverse('student_list', args=['active']))

    #GET an empty form
    else:
        student_form = StudentForm()

return render_to_response('priviostudio/create_student.html', {
    'student_form': student_form,
})

And in the student edit view (which will probably be combined with the create_student view) I have this for GET:

student_form_initial = {
        'username': user_instance.username if user_instance.has_usable_password() else '',
        'password': user_instance.password if user_instance.has_usable_password() else '',
    }
    student_form = StudentForm(instance=user_instance, initial=student_form_initial)

And in POST, if the teacher presents a new username and a valid password, I will just install them on the user instance.

Thanks for all the ideas.

+3
source share
4 answers

The auth app model Userhas a method set_unusable_password; this probably does what you want without requiring an extension of the model.

+3

Django is_active.

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

, , .

, , , , - is_active = True .

Django is_active, .

, , , , slug , .

- , Django .

+2

, , , , . , .

+1

I avoid subclassing the user. Instead, you can create your own authenticator that allows you to check group membership for login.

"""
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 may contain a field indicating whether the student is allowed to log in. Also see http://docs.djangoproject.com/en/dev/howto/auth-remote-user/#attributes .

0
source

Source: https://habr.com/ru/post/1743654/


All Articles