The site I'm working on involves teachers creating student objects. The teacher can choose to make it possible for a student to log into the site (to check calendars, etc) OR the teacher can choose to use the student object only for record keeping and not allow the student to log in. In the student creation form, if the teacher supplies a username and a password, it should create an object of the first kind - one that can log in, i.e. a regular User object. If the teacher does not supply a username/password, it should create the second type. The other requirement is that the teacher should be able to go in later and change a non-logging-in student to the other kind. What's the best way to design for this scenario? Subclass User and make username and password not required? What else would this affect?
Edit: I ended up using User.set_unusable_password(). Here's the code - I've left out other forms, etc, that I'm also using in my view:
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')
Note that username and password are not required in 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 view to edit a student (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 submits a new username and valid password, I'll just set those on the User instance.
Thanks for the ideas everyone.