2010-05-01 59 views
3

我正在處理的網站涉及教師創建學生對象。教師可以選擇讓學生登錄網站(查看日曆等),或者教師可以選擇僅將學生對象用於記錄保存,而不允許學生登錄。在學生創建形式,如果教師提供用戶名和密碼,它應該創建第一種對象 - 可以登錄的對象,即常規用戶對象。如果教師不提供用戶名/密碼,則應創建第二種類型。另一個要求是,教師應該能夠晚點入學,並將非登錄學生轉爲其他種類。設計這種情況的最佳方式是什麼?子類用戶並且不需要用戶名和密碼?這會影響到什麼?Django設計問題:擴展用戶使無法登錄的用戶

編輯: 我結束了使用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) 

,並在後期,如果教師提交了新的用戶名和有效的密碼,我只需在User實例上進行設置。

感謝您的想法大家。

回答

3

中的驗證應用程序的User模型具有set_unusable_password方法;這可能是你想要的,而不需要擴展模型。

+0

問題是我還必須生成一個隨機的用戶名(因爲用戶名有unique = True且沒有空白= True),這也會顯示在表單上,​​並且可能會讓教師感到困惑。 – UrLicht 2010-05-01 20:42:55

1

你可能會考慮把所有的學生都一個樣的對象 - 而不是用戶 - 然後補充與何老師,使學生以用戶身份登錄的對象模型,這兩個模型對象的組成將解決你要相當乾淨。

+0

這似乎是一個很好的做法,但是看起來形式可能會有點混亂。我會去試試這個。 – UrLicht 2010-05-01 20:30:09

+0

我遇到了麻煩:我仍然想在用戶上使用first_name,last_name和email。這樣做需要將這些數據保存在非用戶對象中並進行同步。 – UrLicht 2010-05-01 21:29:22

0

我woud避免子類用戶。相反,您可能需要創建一個自定義身份驗證器,以允許您檢查組成員的登錄能力。

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

學生模型可以包含一個字段,表示如果學生被允許登錄。 也看看http://docs.djangoproject.com/en/dev/howto/auth-remote-user/#attributes

2

Django的默認的用戶模型有一個IS_ACTIVE場。

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

你可能想使用它。

當老師決定,他們希望用戶能夠登錄,您的代碼將只設置學生用戶IS_ACTIVE =真,反之亦然這樣。

另外根據上面的文檔鏈接,Django的默認身份驗證表單和權限方法檢查is_active標誌,這是已經爲您完成的一些工作。

您可能還需要爲該學生生成一個用戶名,但如果提供該名稱,則可以使用名稱中的子彈輕鬆地執行此操作。

對我來說,讓學生與教師區分的最明顯的方式是真正的組合,Django也爲此提供了機制。