3

我正在开发的网站涉及教师创建学生对象。教师可以选择让学生可以登录网站(查看日历等),或者教师可以选择仅将学生对象用于记录保存而不允许学生登录。在学生创建中表单中,如果教师提供用户名和密码,它应该创建第一种对象 - 可以登录的对象,即常规用户对象。如果教师没有提供用户名/密码,则应创建第二种类型。另一个要求是教师应该能够稍后进入并将未登录的学生更改为其他类型。为这种情况设计的最佳方法是什么?子类用户并使用户名和密码不需要?这还会影响什么?

编辑: 我最终使用了 User.set_unusable_password()。这是代码 - 我省略了其他表格等,我也在我的视图中使用:

形式

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')

请注意,表单中不需要用户名和密码。

看法

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,
})

在编辑学生的视图中(可能会与 create_student 视图相结合)我有这个用于 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)

在 POST 中,如果教师提交了新的用户名和有效密码,我将在 User 实例上设置它们。

感谢大家的想法。

4

4 回答 4

3

auth 应用的User模型有一个set_unusable_password方法;这可能不需要扩展模型就可以满足您的需求。

于 2010-05-01T20:36:15.820 回答
2

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 也为此提供了机制。

于 2010-05-02T10:24:54.690 回答
1

您可能会考虑让所有学生成为一种对象 - 而不是用户 - 然后用教师允许学生登录的用户对象补充该模型。这两个模型对象的组合将相当干净地解决您想要的问题。

于 2010-05-01T20:26:45.713 回答
0

我会避免子类化用户。相反,您可能想要创建一个自定义身份验证器,以允许您检查组成员身份的登录功能。

"""
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

Student 模型可以包含一个字段,指示是否允许学生登录。还可以查看http://docs.djangoproject.com/en/dev/howto/auth-remote-user/#attributes

于 2010-05-01T20:47:25.603 回答