Before I go any further on my project I think I need to sort out my user model. At the start of the project I implemented a Custom User as explained here but I haven’t touched it since. My project is a gradebook so there is lots of functionality/objects tied to students: classrooms, assessments, grades. So far I have Student
model that is not connected to the User model.
Models
class CustomUser(AbstractUser):
pass
def __str__(self):
return self.username
class Student(models.Model):
classroom = models.ForeignKey(Classroom, on_delete=models.CASCADE)
student_first = models.CharField(default='John', max_length=30)
student_last = models.CharField(default='Smith', max_length=30)
nickname = models.CharField(default='JohnS', max_length=31)
email = models.EmailField(max_length=50)
attend = models.BooleanField(default=True)
do_not_pick = models.BooleanField(default=False)
def __str__(self):
return self.nickname
View
def addmultistudent(request, classroom_id):
"""Add multiple students at once."""
classblock = get_object_or_404(Classroom, pk=classroom_id)
context = {'classblock': classblock}
if request.method == 'POST':
#form contains one TextField with a list of names
form = StudentInputForm(request.POST)
if form.is_valid():
students = form.save(commit=False)
# save the classroom that the student belongs to
input_list = []
input_list = students.name_list.split('\n')
output_list = []
for line in input_list:
line = line.strip('\r')
all_names = line.split()
num_names = len(all_names)
if num_names == 2:
last = all_names[1]
else:
last = ' '
nick = all_names[0] + last[:1]
# create the object and then add the attributes
new_student = Student()
new_student.student_last = last
new_student.student_first = all_names[0]
new_student.nickname = nick
new_student.classroom = classblock
new_student.email = nick + "@domain.com"
# create the list to be bulk added
output_list.append(new_student)
Student.objects.bulk_create(output_list)
form = StudentInputForm(None)
context['form'] = form
return render(request, "gradebook/addmultistudent.html", context)
else:
context['form'] = form
return render(request, "gradebook/addmultistudent.html", context)
else:
form = StudentInputForm(None)
context['form'] = form
return render(request, "gradebook/addmultistudent.html", context)
urls
app_name = 'gradebook'
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
path('signup/', SignUpView.as_view(), name='signup'),
path('courses/', views.courses, name='courses'),
path('classroom/', views.classroom, name='classroom'),
path('studentsetup/', views.studentsetup, name='studentsetup'),
path('classroom/<int:pk>/',
views.ClassroomDetailView.as_view(), name='classdetail'),
path('addmultistudent/<int:classroom_id>/',
views.addmultistudent, name='addmultistudent'),
]
template
<form action="" method="post">
{% csrf_token %} {{ form|crispy }}
<div class="form-group">
<button type="submit" class="btn btn-default">Submit</button>
</div>
</form>
My hunch is that I should use a OneToOneField in my Student
model, connected to CustomUser
, as discussed in this thread. The unknown part for me is how I’m creating these student users. I have a form where a list of users are cut’n’pasted into. My view then parses the list and creates the student objects. Hopefully I can still use this.
My question is, looking at my code above does it seem reasonable to connect each student
to the CustomUser
with a OneToOneField? Or is there another method I should be looking at? Also, I would have to add password fields to the student model and then in the view I maybe I can generate random passwords? Or can a student user “recover” a password when they try to login?