3

私が取り組んでいるサイトには、教師が生徒のオブジェクトを作成することが含まれています。教師は、生徒がサイトにログインできるようにする(カレンダーなどを確認する)か、生徒のオブジェクトを記録保持のみに使用し、生徒にログインを許可しないようにするかを選択できます。生徒の作成フォームでは、教師がユーザー名とパスワードを提供する場合、第1種のオブジェクト、つまりログインできるオブジェクト、つまり通常のUserオブジェクトを作成する必要があります。教師がユーザー名/パスワードを提供しない場合は、2番目のタイプを作成する必要があります。もう1つの要件は、教師が後で参加して、ログインしていない生徒を別の種類に変更できるようにすることです。このシナリオを設計するための最良の方法は何ですか?ユーザーをサブクラス化し、ユーザー名とパスワードを不要にしますか?これは他に何に影響しますか?

編集: 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

認証アプリのUserモデルにはset_unusable_passwordメソッドがあります。これはおそらく、モデルを拡張する必要なく、目的を達成します。

于 2010-05-01T20:36:15.820 に答える
2

Django のデフォルトの User モデルには is_active フィールドがあります。

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

あなたはおそらくそれを使いたいでしょう。

そうすれば、教師がユーザーにログインできるようにすることを決定した場合、コードは生徒のユーザーを is_active=True に設定するだけで済み、その逆も同様です。

また、上記のドキュメント リンクによると、Django のデフォルトの認証フォームとパーミッション メソッドは is_active フラグをチェックするため、すでに行われている作業の一部です。

おそらく学生のユーザー名も生成する必要がありますが、名前が提供されている場合は、名前からスラッグを使用して簡単に行うことができます。

学生と教師を区別する最も明白な方法は、実際にはグループであり、Django はそのためのメカニズムも提供します。

于 2010-05-02T10:24:54.690 に答える
1

すべての生徒をユーザーではなく1種類のオブジェクトにしてから、教師が生徒にログインを許可したユーザーオブジェクトでそのモデルを補足することを検討できます。これら2つのモデルオブジェクトの構成により、必要なものをかなりきれいに解決できます。

于 2010-05-01T20:26:45.713 に答える
0

User のサブクラス化は避けたいと思います。代わりに、ログイン機能のグループ メンバーシップを確認できるカスタム オーセンティケータを作成することをお勧めします。

"""
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 に答える